﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;
using System.Text;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Shapes;

namespace FasterWPF
{
    public static class ScrollViewerExt
    {
        public static ScrollViewer SetBackgroundColor(this ScrollViewer chain, Brush brush)
        {
            Brush newBrush = (brush);
            chain.Background = newBrush;
            return chain;
        }

        public static ScrollViewer Initialize(this ScrollViewer source, double width, double height, ContainerType containerType, Thickness margin, int? rowSpan, int? colSpan)
        {
            //Force the Aero theme by default to assure the structure of the Listbox
            Uri uri = new Uri("/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml", UriKind.Relative);
            source.Resources.MergedDictionaries.Add(Application.LoadComponent(uri) as ResourceDictionary);

            if (rowSpan != null)
            {
                Grid.SetRowSpan(source, (int)rowSpan);
            }

            if (colSpan != null)
            {
                Grid.SetColumnSpan(source, (int)colSpan);
            }
            source.Margin = margin;
            source.Width = width;
            source.Height = height;
            source.SetContainerType(containerType);
            IComposite icomp = CompositeTypeHelper.CreateIComposite<ScrollViewer>(source);
            source.SetIComposite<ScrollViewer>(icomp);

            //STORE SETTING BUILD CHAIN AND GET CHAIN?!?  Put these in a Composite implements an interface
            ScrollViewerParent svbsr = new ScrollViewerParent();
            source.StoreSetting<ScrollViewer>("IParent", svbsr);
            source.StoreSetting<ScrollViewer>("IScrollViewerStrategy", svbsr);

            source.AddItemBorder(Brushes.Gray, new Thickness(1, 1, 1, 1)); //default Border     
            source.StoreSetting<ScrollViewer>("BorderSettings", new BorderSettings() { Width = double.NaN, Height = double.NaN, BorderBrush = Brushes.Gray, BorderThickness = new Thickness(0, 0, 0, 0), CornerRadius = new CornerRadius(0), Padding = new Thickness(0) });

            return source;
        }
        
        public static T SetVerticalScrollThumbToBeFixedSizeNotProportional<T>(this T chain)
             where T : FrameworkElement
        {
            Track tr = chain.GetVerticalScrollTrack();
            tr.ViewportSize = 0;
            return chain;
        }

        public static T SetHorizontalScrollThumbToBeFixedSizeNotProportional<T>(this T chain)
             where T : FrameworkElement
        {
            Track tr = chain.GetHorizontalScrollTrack();
            tr.ViewportSize = 0;
            return chain;
        }

        /// <summary>
        /// Logical scrolling seems buggy. Therefore, always force physical scrolling by setting CanContentScroll equal to false
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        public static void SetCanContentScroll<T>(T source)
                where T : FrameworkElement
        {
            ScrollViewer closeOverViewer = source.GetScrollViewer();
            closeOverViewer.CanContentScroll = false;  //Logical scrolling seems buggy. Therefore, always force physical scrolling

            //    source.GetVerticalPageDownButton().ClickMode = ClickMode.Press;
            //      source.GetVerticalPageDownButton().Delay = (int)source.GetSettingsDictionary()["ScrollViewerPageDownDelay"];
            //      source.GetVerticalPageDownButton().Interval = (int)source.GetSettingsDictionary()["ScrollViewerPageDownInterval"];
        }
        
        #region BeginSettings...EndSettings

        #region Thumb Step and Drag Delta

        public static SettingsChain<T> SetVerticalScrollThumbToBeFixedSizeNotProportional<T>(this SettingsChain<T> chain)
             where T : FrameworkElement
        {
            chain.Item2.Add(((container) =>
            {
                return container.SetVerticalScrollThumbToBeFixedSizeNotProportional<T>();
            }));

            return chain;
        }

        public static SettingsChain<T> SetHorizontalScrollThumbToBeFixedSizeNotProportional<T>(this SettingsChain<T> chain)
             where T : FrameworkElement
        {
            chain.Item2.Add(((container) =>
            {
                return container.SetHorizontalScrollThumbToBeFixedSizeNotProportional<T>();
            }));
            return chain;
        }

       #endregion

        #region ScrollViewer Settings
                
        public static SettingsChain<T> SetVerticalScrollBarColor<T>(this SettingsChain<T> chain, Brush brush)
             where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalScrollBarColor<T>(brush);

            return chain;
        }

        public static SettingsChain<T> SetVerticalScrollBarColor<T>(this SettingsChain<T> chain, byte red, byte green, byte blue, byte alpha)
             where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalScrollBarColor<T>(red, green, blue, alpha);

            return chain;
        }

        public static SettingsChain<T> SetScrollViewerCornerRectangleColor<T>(this SettingsChain<T> chain, Brush brush)
             where T : FrameworkElement
        {
            ((T)chain.Item1).SetScrollViewerCornerRectangleColor<T>(brush);
            
            return chain;
        }

        public static SettingsChain<T> SetScrollViewerCornerRectangleColor<T>(this SettingsChain<T> chain, byte red, byte green, byte blue, byte alpha) where T : FrameworkElement
        {
            ((T)chain.Item1).SetScrollViewerCornerRectangleColor<T>(red, green, blue, alpha);
            
            return chain;
        }

        public static SettingsChain<T> SetVerticalScrollDownButtonTemplate<T>(this SettingsChain<T> chain, string controlTemplateXAML, string glyphPath)
             where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalScrollDownButtonTemplate<T>(controlTemplateXAML, glyphPath);

            return chain;
        }

        public static SettingsChain<T> SetVerticalScrollDownButtonColors<T>(this SettingsChain<T> chain, string backgroundColor, string moveOverColor, string pressedColorTop, string pressedColorMid, string pressedColorBottom, string glyphColor, string pressedGlyphColor, string glyphPath) where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalScrollDownButtonColors<T>(backgroundColor, moveOverColor, pressedColorTop, pressedColorMid, pressedColorBottom, glyphColor, pressedGlyphColor, glyphPath);

            return chain;
        }

        public static SettingsChain<T> SetVerticalScrollDownButtonColors<T>(this SettingsChain<T> chain, string backgroundColor, string mouseOverColor, string pressedColorTop, string pressedColorMid, string pressedColorBottom, string cornerRadius, string borderColor, Thickness borderThickness, string glyphColor, string pressedGlyphColor, string glyphPath)
            where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalScrollDownButtonColors<T>(backgroundColor, mouseOverColor, pressedColorTop, pressedColorMid, pressedColorBottom, cornerRadius, borderColor, borderThickness, glyphColor, pressedGlyphColor, glyphPath);

            return chain;
        }

        public static SettingsChain<T> SetVerticalScrollUpButtonTemplate<T>(this SettingsChain<T> chain, string controlTemplateXAML, string glyphPath, string mouseOverColor) where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalScrollUpButtonTemplate<T>(controlTemplateXAML, glyphPath, mouseOverColor);

            return chain;
        }

        public static SettingsChain<T> SetVerticalScrollUpButtonColors<T>(this SettingsChain<T> chain, string backgroundColor, string mouseOverColor, string pressedColorTop, string pressedColorMid, string pressedColorBottom, string glyphColor, string pressedGlyphColor, string glyphPath) where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalScrollUpButtonColors<T>(backgroundColor, mouseOverColor, pressedColorTop, pressedColorMid, pressedColorBottom, glyphColor, pressedGlyphColor, glyphPath);

            return chain;
        }

        public static SettingsChain<T> SetVerticalScrollUpButtonColors<T>(this SettingsChain<T> chain, string backgroundColor, string mouseOverColor, string pressedColorTop, string pressedColorMid, string pressedColorBottom, string cornerRadius, string borderColor, Thickness borderThickness, string glyphColor, string pressedGlyphColor, string glyphPath) where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalScrollUpButtonColors<T>(backgroundColor, mouseOverColor, pressedColorTop, pressedColorMid, pressedColorBottom, cornerRadius, borderColor, borderThickness, glyphColor, pressedGlyphColor, glyphPath);

            return chain;
        }

        public static SettingsChain<T> SetVerticalScrollThumbColors<T>(this SettingsChain<T> chain, string backgroundColor, string mouseOverColor, string pressedColor, string borderColor, string borderThickness, string cornerRadius) where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalScrollThumbColors<T>(backgroundColor, mouseOverColor, pressedColor, borderColor, borderThickness, cornerRadius);

            return chain;
        }

        public static SettingsChain<T> SetVerticalScrollThumbColors<T>(this SettingsChain<T> chain, byte red, byte green, byte blue, byte alpha, string mouseOverColor, string pressedColor, string borderColor, string borderThickness, string cornerRadius)
            where T : FrameworkElement
        {
          ((T)chain.Item1).SetVerticalScrollThumbColors<T>(red, green, blue, alpha, mouseOverColor, pressedColor, borderColor, borderThickness, cornerRadius);

            return chain;
        }

        public static SettingsChain<T> SetVerticalPageDownButtonTemplate<T>(this SettingsChain<T> chain, string controlTemplateXAML)
            where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalPageDownButtonTemplate<T>(controlTemplateXAML);

            return chain;
        }

        public static SettingsChain<T> SetVerticalPageDownButtonColors<T>(this SettingsChain<T> chain, string backgroundColor, string pressedColorTop, string pressedColorMid, string pressedColorBottom, string cornerRadius, string borderColor, Thickness borderThickness)
            where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalPageDownButtonColors<T>(backgroundColor, pressedColorTop, pressedColorMid, pressedColorBottom, cornerRadius, borderColor, borderThickness);

            return chain;
        }

        public static SettingsChain<T> SetVerticalPageDownButtonColors<T>(this SettingsChain<T> chain, string backgroundColor, string pressedColorTop, string pressedColorMid, string pressedColorBottom) where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalPageDownButtonColors<T>(backgroundColor, pressedColorTop, pressedColorMid, pressedColorBottom);

            return chain;
        }

        public static SettingsChain<T> SetVerticalPageDownButtonColors<T>(this SettingsChain<T> chain, byte red, byte green, byte blue, byte alpha, string pressedColorTop, string pressedColorMid, string pressedColorBottom) where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalPageDownButtonColors<T>(red, green, blue, alpha, pressedColorTop, pressedColorMid, pressedColorBottom);

            return chain;
        }

        public static SettingsChain<T> SetVerticalPageDownButtonColors<T>(this SettingsChain<T> chain, byte red, byte green, byte blue, byte alpha, string pressedColorTop, string pressedColorMid, string pressedColorBottom, string buttonCornerRadius, string borderColor, Thickness borderThickness) where T : FrameworkElement
        {
             ((T)chain.Item1).SetVerticalPageDownButtonColors<T>(red, green, blue, alpha, pressedColorTop, pressedColorMid, pressedColorBottom, buttonCornerRadius, borderColor, borderThickness);

            return chain;
        }

        public static SettingsChain<T> SetVerticalPageUpButtonTemplate<T>(this SettingsChain<T> chain, string controlTemplateXAML)
            where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalPageUpButtonTemplate<T>(controlTemplateXAML);

            return chain;
        }

        public static SettingsChain<T> SetVerticalPageUpButtonColors<T>(this SettingsChain<T> chain, string backgroundColor, string pressedColorTop, string pressedColorMid, string pressedColorBottom, string cornerRadius, string regularBorderColor, Thickness borderThickness) where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalPageUpButtonColors<T>(backgroundColor, pressedColorTop, pressedColorMid, pressedColorBottom, cornerRadius, regularBorderColor, borderThickness);

            return chain;
        }

        public static SettingsChain<T> SetVerticalPageUpButtonColors<T>(this SettingsChain<T> chain, string backgroundColor, string pressedColorTop, string pressedColorMid, string pressedColorBottom) where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalPageUpButtonColors<T>(backgroundColor, pressedColorTop, pressedColorMid, pressedColorBottom);

            return chain;
        }

        public static SettingsChain<T> SetVerticalPageUpButtonColors<T>(this SettingsChain<T> chain, byte red, byte green, byte blue, byte alpha, string pressedColorTop, string pressedColorMid, string pressedColorBottom) where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalPageUpButtonColors<T>(red, green, blue, alpha, pressedColorTop, pressedColorMid, pressedColorBottom);

            return chain;
        }

        public static SettingsChain<T> SetVerticalPageUpButtonColors<T>(this SettingsChain<T> chain, string pressedColorTop, string pressedColorMid, string pressedColorBottom, string pressedColor4, byte red, byte green, byte blue, byte alpha, string buttonCornerRadius, string regularBorderColor, Thickness borderThickness) where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalPageUpButtonColors<T>(pressedColorTop, pressedColorMid, pressedColorBottom, pressedColor4, red, green, blue, alpha, buttonCornerRadius, regularBorderColor, borderThickness);

            return chain;
        }

        public static SettingsChain<T> SetVerticalScrollThumbTemplate<T>(this SettingsChain<T> chain, string controlTemplateXAML)
            where T : FrameworkElement
        {
            ((T)chain.Item1).SetVerticalScrollThumbTemplate<T>(controlTemplateXAML);

            return chain;
        }

        public static SettingsChain<T> SetHorizontalScrollBarColor<T>(this SettingsChain<T> chain, Brush brush)
            where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalScrollBarColor<T>(brush);

            return chain;
        }

        public static SettingsChain<T> SetHorizontalScrollBarColor<T>(this SettingsChain<T> chain, byte red, byte green, byte blue, byte alpha)
            where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalScrollBarColor<T>(red, green, blue, alpha);

            return chain;
        }

        public static SettingsChain<T> SetHorizontalScrollRightButtonTemplate<T>(this SettingsChain<T> chain, string controlTemplateXAML, string glyphPath) where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalScrollRightButtonTemplate<T>(controlTemplateXAML, glyphPath);

            return chain;
        }

        public static SettingsChain<T> SetHorizontalScrollRightButtonColors<T>(this SettingsChain<T> chain, string backgroundColor, string mouseOverColor, string pressedColorLeft, string pressedColorMid, string pressedColorRight, string glyphColor, string pressedGlyphColor, string glyphPath) where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalScrollRightButtonColors<T>(backgroundColor, mouseOverColor, pressedColorLeft, pressedColorMid, pressedColorRight, glyphColor, pressedGlyphColor, glyphPath);

            return chain;
        }

        public static SettingsChain<T> SetHorizontalScrollRightButtonColors<T>(this SettingsChain<T> chain, string backgroundColor, string mouseOverColor, string pressedColorLeft, string pressedColorMid, string pressedColorRight, string cornerRadius, string borderColor, Thickness borderThickness, string glyphColor, string pressedGlyphColor, string glyphPath)
            where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalScrollRightButtonColors<T>(backgroundColor, mouseOverColor, pressedColorLeft, pressedColorMid, pressedColorRight, cornerRadius, borderColor, borderThickness, glyphColor, pressedGlyphColor, glyphPath);

            return chain;
        }

        public static SettingsChain<T> SetHorizontalScrollLeftButtonTemplate<T>(this SettingsChain<T> chain, string controlTemplateXAML, string glyphPath) where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalScrollLeftButtonTemplate<T>(controlTemplateXAML, glyphPath);
            return chain;
        }

        public static SettingsChain<T> SetHorizontalScrollLeftButtonColors<T>(this SettingsChain<T> chain, string backgroundColor, string mouseOverColor, string pressedColorLeft, string pressedColorMid, string pressedColorRight, string glyphColor, string pressedGlyphColor, string glyphPath) where T : FrameworkElement
        {
          ((T)chain.Item1).SetHorizontalScrollLeftButtonColors<T>(backgroundColor, mouseOverColor, pressedColorLeft, pressedColorMid, pressedColorRight, glyphColor, pressedGlyphColor, glyphPath);

            return chain;
        }

        public static SettingsChain<T> SetHorizontalScrollLeftButtonColors<T>(this SettingsChain<T> chain, string backgroundColor, string mouseOverColor, string pressedColorLeft, string pressedColorMid, string pressedColorRight, string cornerRadius, string borderColor, Thickness borderThickness, string glyphColor, string pressedGlyphColor, string glyphPath) where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalScrollLeftButtonColors<T>(backgroundColor, mouseOverColor, pressedColorLeft, pressedColorMid, pressedColorRight, cornerRadius, borderColor, borderThickness, glyphColor, pressedGlyphColor, glyphPath);

            return chain;
        }

        public static SettingsChain<T> SetHorizontalScrollThumbColors<T>(this SettingsChain<T> chain, string backgroundColor, string mouseOverColor, string pressedColor, string borderColor, string borderThickness, string cornerRadius)
            where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalScrollThumbColors<T>(backgroundColor, mouseOverColor, pressedColor, borderColor, borderThickness, cornerRadius);

            return chain;
        }

        public static SettingsChain<T> SetHorizontalScrollThumbColors<T>(this SettingsChain<T> chain, byte red, byte green, byte blue, byte alpha, string mouseOverColor, string pressedColor, string borderColor, string borderThickness, string cornerRadius)
            where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalScrollThumbColors<T>(red, green, blue, alpha, mouseOverColor, pressedColor, borderColor, borderThickness, cornerRadius);

           return chain;
        }

        public static SettingsChain<T> SetHorizontalScrollThumbTemplate<T>(this SettingsChain<T> chain, string controlTemplateXAML)
            where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalScrollThumbTemplate<T>(controlTemplateXAML);

            return chain;
        }

        public static SettingsChain<T> SetHorizontalPageRightButtonTemplate<T>(this SettingsChain<T> chain, string controlTemplateXAML)
            where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalPageRightButtonTemplate<T>(controlTemplateXAML);

            return chain;
        }

        public static SettingsChain<T> SetHorizontalPageRightButtonColors<T>(this SettingsChain<T> chain, string backgroundColor, string pressedColorLeft, string pressedColorMid, string pressedColorRight) where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalPageRightButtonColors<T>(backgroundColor, pressedColorLeft, pressedColorMid, pressedColorRight);

            return chain;
        }

        public static SettingsChain<T> SetHorizontalPageRightButtonColors<T>(this SettingsChain<T> chain, byte red, byte green, byte blue, byte alpha, string pressedColorLeft, string pressedColorMid, string pressedColorRight) where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalPageRightButtonColors<T>(red, green, blue, alpha, pressedColorLeft, pressedColorMid, pressedColorRight);

            return chain;
        }

        public static SettingsChain<T> SetHorizontalPageRightButtonColors<T>(this SettingsChain<T> chain, string backgroundColor, string pressedColorLeft, string pressedColorMid, string pressedColorRight, string borderColor, string cornerRadius, Thickness borderThickness) where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalPageRightButtonColors<T>(backgroundColor, pressedColorLeft, pressedColorMid, pressedColorRight, borderColor, cornerRadius, borderThickness);

            return chain;
        }

        public static SettingsChain<T> SetHorizontalPageRightButtonColors<T>(this SettingsChain<T> chain, byte red, byte green, byte blue, byte alpha, string pressedColorLeft, string pressedColorMid, string pressedColorRight, string regularBorderColor, string buttonCornerRadius, Thickness borderThickness) where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalPageRightButtonColors<T>(red, green, blue, alpha, pressedColorLeft, pressedColorMid, pressedColorRight, regularBorderColor, buttonCornerRadius, borderThickness);

            return chain;
        }

        public static SettingsChain<T> SetHorizontalPageLeftButtonTemplate<T>(this SettingsChain<T> chain, string controlTemplateXAML)
             where T : FrameworkElement
        {
           ((T)chain.Item1).SetHorizontalPageLeftButtonTemplate<T>(controlTemplateXAML);
            return chain;
        }

        public static SettingsChain<T> SetHorizontalPageLeftButtonColors<T>(this SettingsChain<T> chain, string backgroundColor, string pressedColorLeft, string pressedColorMid, string pressedColorRight)
           where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalPageLeftButtonColors<T>(backgroundColor, pressedColorLeft, pressedColorMid, pressedColorRight);

            return chain;
        }

        public static SettingsChain<T> SetHorizontalPageLeftButtonColors<T>(this SettingsChain<T> chain, byte red, byte green, byte blue, byte alpha, string pressedColorLeft, string pressedColorMid, string pressedColorRight)
             where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalPageLeftButtonColors<T>(red, green, blue, alpha, pressedColorLeft, pressedColorMid, pressedColorRight);

            return chain;
        }

        public static SettingsChain<T> SetHorizontalPageLeftButtonColors<T>(this SettingsChain<T> chain, string backgroundColor, string pressedColorLeft, string pressedColorMid, string pressedColorRight, string borderColor, string cornerRadius, Thickness borderThickness) where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalPageLeftButtonColors<T>(backgroundColor, pressedColorLeft, pressedColorMid, pressedColorRight, borderColor, cornerRadius, borderThickness);

            return chain;
        }

        public static SettingsChain<T> SetHorizontalPageLeftButtonColors<T>(this SettingsChain<T> chain, byte red, byte green, byte blue, byte alpha, string pressedColorLeft, string pressedColorMid, string pressedColorRight, string regularBorderColor, string buttonCornerRadius, Thickness borderThickness) where T : FrameworkElement
        {
            ((T)chain.Item1).SetHorizontalPageLeftButtonColors<T>(red, green, blue, alpha, pressedColorLeft, pressedColorMid, pressedColorRight, regularBorderColor, buttonCornerRadius, borderThickness);

            return chain;
        }

        #endregion
        
        #endregion
        
        #region ScrollViewer Settings

        public static ScrollViewer GetScrollViewer<T>(this T chain)
                where T : FrameworkElement
        {
            var settings = chain.GetSettingsDictionary();
            IScrollViewerStrategy svComposite = null;
            if (settings.Keys.Contains("IScrollViewerStrategy"))
            {
               svComposite = (IScrollViewerStrategy)settings["IScrollViewerStrategy"];
            }

            return svComposite.GetScrollViewer(chain);           
        }

        public static ScrollBar GetVerticalScrollBar<T>(this T chain)
             where T : FrameworkElement
        {
            ScrollViewer scroller = GetScrollViewer<T>(chain);

            scroller.ApplyTemplate();
            Grid g = (Grid)scroller.Template.FindName("Grid", scroller);

            ScrollBar verticalBar = null;

            if(g!=null)
            {
                verticalBar = (ScrollBar)g.Children[2];
            }
            else
            {
                verticalBar = (ScrollBar)scroller.Template.FindName("PART_VerticalScrollBar", scroller);
            }

            return verticalBar;
        }

        public static T SetVerticalScrollBarColor<T>(this T chain, Brush brush)
             where T : FrameworkElement
        {
            ScrollBar scrBar = GetVerticalScrollBar<T>(chain);

            if (scrBar != null && brush != null)
            {
                scrBar.Background = brush;
            }

            return chain;
        }

        public static T SetVerticalScrollBarColor<T>(this T chain, byte red, byte green, byte blue, byte alpha)
             where T : FrameworkElement
        {
            ScrollBar scrBar = GetVerticalScrollBar<T>(chain);
            if (scrBar != null)
            {
                scrBar.Background = (Brush)(new System.Windows.Media.SolidColorBrush(new
                System.Windows.Media.Color()
                {
                    R = red,
                    G = green,
                    B = blue,
                    A = alpha
                }));
            }

            return chain;
        }

        public static T SetScrollViewerCornerRectangleColor<T>(this T chain, Brush brush)
             where T : FrameworkElement
        {
            ScrollViewer scroller = GetScrollViewer<T>(chain);

            if (scroller != null && brush != null)
            {
                scroller.ApplyTemplate();
                Grid g = (Grid)scroller.Template.FindName("Grid", scroller);
                if (g != null)
                {
                    Rectangle r = (Rectangle)g.Children[0];
                    r.Fill = brush;
                }
            }

            return chain;
        }

        public static T SetScrollViewerCornerRectangleColor<T>(this T chain, byte red, byte green, byte blue, byte alpha) where T : FrameworkElement
        {
            ScrollViewer scroller = GetScrollViewer<T>(chain);

            if (scroller != null)
            {
                scroller.ApplyTemplate();
                Grid g = (Grid)scroller.Template.FindName("Grid", scroller);
                if (g != null)
                {
                    Rectangle r = (Rectangle)g.Children[0];
                    r.Fill = (Brush)(new System.Windows.Media.SolidColorBrush(new
                    System.Windows.Media.Color()
                    {
                        R = red,
                        G = green,
                        B = blue,
                        A = alpha
                    }));
                }
            }
            return chain;
        }

        public static Track GetVerticalScrollTrack<T>(this T chain)
            where T : FrameworkElement
        {
            ScrollBar verticalBar = chain.GetVerticalScrollBar<T>();
            verticalBar.ApplyTemplate();
            return verticalBar.Track;
        }

        public static Thumb GetVerticalScrollThumb<T>(this T chain)
            where T : FrameworkElement
        {
            Track tr = chain.GetVerticalScrollTrack();
            tr.ApplyTemplate();
            return tr.Thumb;
        }

        public static RepeatButton GetVerticalScrollUpButton<T>(this T chain)
            where T : FrameworkElement
        {
            ScrollBar verticalBar = chain.GetVerticalScrollBar<T>();
            verticalBar.ApplyTemplate();
            Grid grid = (Grid)verticalBar.Template.FindName("Bg", verticalBar); //Grid
            RepeatButton upButton = ((RepeatButton)grid.Children[0]);
            return upButton;
        }

        public static RepeatButton GetVerticalScrollDownButton<T>(this T chain)
            where T : FrameworkElement
        {
            ScrollBar verticalBar = chain.GetVerticalScrollBar<T>();
            verticalBar.ApplyTemplate();
            Grid grid = (Grid)verticalBar.Template.FindName("Bg", verticalBar); //Grid
            RepeatButton downButton = ((RepeatButton)grid.Children[2]);
            return downButton;
        }

        public static T SetVerticalScrollDownButtonTemplate<T>(this T chain, string controlTemplateXAML, string glyphPath)
             where T : FrameworkElement
        {
            RepeatButton repBtn = chain.GetVerticalScrollDownButton<T>();
            repBtn.Content = glyphPath;
            ControlTemplate cTemplate = new System.Windows.Controls.ControlTemplate(typeof(RepeatButton));
            string xaml = controlTemplateXAML;

            MemoryStream sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));
            ParserContext pc = new ParserContext();
            pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
            pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
            var repBtnTemplate = (ControlTemplate)XamlReader.Load(sr, pc);
            repBtn.Template = repBtnTemplate;
            return chain;
        }

        public static T SetVerticalScrollDownButtonColors<T>(this T chain, string backgroundColor, string moveOverColor, string pressedColorTop, string pressedColorMid, string pressedColorBottom, string glyphColor, string pressedGlyphColor, string glyphPath) where T : FrameworkElement
        {
            string cornerRadius = "0";
            string borderColor = "Gray";
            Thickness borderThickness = new Thickness(0, 0, 0, 0);

            chain.SetVerticalScrollDownButtonColors<T>(backgroundColor, moveOverColor, pressedColorTop, pressedColorMid, pressedColorBottom, cornerRadius, borderColor, borderThickness, glyphColor, pressedGlyphColor, glyphPath);

            return chain;
        }

        public static T SetVerticalScrollDownButtonColors<T>(this T chain, string backgroundColor, string mouseOverColor, string pressedColorTop, string pressedColorMid, string pressedColorBottom, string cornerRadius, string borderColor, Thickness borderThickness, string glyphColor, string pressedGlyphColor, string glyphPath)
            where T : FrameworkElement
        {
            string disabledColor = "Gray"; //this needs to target the  TargetName=\"Border\" in order to work
            string pressedColor4 = "Transparent";

            string controlTemplateStr = "<ControlTemplate TargetType=\"{x:Type RepeatButton}\"><ControlTemplate.Resources>  <Color x:Key=\"DisabledForeColor\">" + disabledColor + "</Color><Color x:Key=\"PressedColor1\">" + pressedColorTop + "</Color><Color x:Key=\"PressedColor2\">" + pressedColorBottom + "</Color><Color x:Key=\"PressedColor3\">" + pressedColorMid + "</Color><Color x:Key=\"PressedColor4\">" + pressedColor4 + "</Color><Color x:Key=\"RegularForeColor\">" + backgroundColor + "</Color><Color x:Key=\"MouseOverColor\">" + mouseOverColor + "</Color><Color x:Key=\"RegularBorderColor\">" + borderColor + "</Color><Color x:Key=\"GlyphForeColor\">" + glyphColor + "</Color><Color x:Key=\"PressedGlyphForeColor\">" + pressedGlyphColor + "</Color><SolidColorBrush x:Key=\"NormalBrush\" Color=\"{StaticResource RegularForeColor}\" /><SolidColorBrush x:Key=\"NormalBorderBrush\" Color=\"{StaticResource RegularBorderColor}\" /> <SolidColorBrush x:Key=\"MouseOverBrush\" Color=\"{StaticResource MouseOverColor}\"/> <SolidColorBrush x:Key=\"DisabledForeBrush\" Color=\"{StaticResource DisabledForeColor}\"/><SolidColorBrush x:Key=\"GlyphBrush\" Color=\"{StaticResource GlyphForeColor}\"/><SolidColorBrush x:Key=\"PressedGlyphBrush\" Color=\"{StaticResource PressedGlyphForeColor}\"/>   <LinearGradientBrush x:Key=\"PressedForeBrush\" StartPoint=\"0,1\" EndPoint=\"0,0\"><GradientBrush.GradientStops><GradientStopCollection><GradientStop Color=\"{StaticResource PressedColor1}\" Offset=\"1.0\"/><GradientStop Color=\"{StaticResource PressedColor2}\" Offset=\"0.3\"/><GradientStop Color=\"{StaticResource PressedColor3}\" Offset=\"0.7\"/><GradientStop Color=\"{StaticResource PressedColor4}\" Offset=\"1.0\"/></GradientStopCollection></GradientBrush.GradientStops></LinearGradientBrush></ControlTemplate.Resources>  <Border Name=\"Border\" Margin=\"1\" CornerRadius=\"" + cornerRadius + "\" Background=\"{StaticResource NormalBrush}\" BorderBrush=\"{StaticResource NormalBorderBrush}\" BorderThickness=\"" + borderThickness + "\"><Path  Name=\"pathGlyph\" HorizontalAlignment=\"Center\" VerticalAlignment=\"Center\" Fill=\"{StaticResource GlyphBrush}\" Data=\"{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}\" /></Border>  <ControlTemplate.Triggers><Trigger Property=\"IsPressed\" Value=\"true\"><Setter TargetName=\"Border\" Property=\"Background\" Value=\"{StaticResource PressedForeBrush}\" /><Setter TargetName=\"pathGlyph\" Property=\"Fill\" Value=\"{StaticResource PressedGlyphBrush}\" /></Trigger><Trigger Property=\"IsEnabled\" Value=\"false\"><Setter Property=\"Foreground\" Value=\"{StaticResource DisabledForeBrush}\"/></Trigger><MultiTrigger><MultiTrigger.Conditions><Condition Property=\"IsMouseOver\" Value=\"true\" /><Condition Property=\"IsPressed\" Value=\"false\" /></MultiTrigger.Conditions><Setter TargetName=\"Border\" Property=\"Background\" Value=\"{StaticResource MouseOverBrush}\"/></MultiTrigger></ControlTemplate.Triggers></ControlTemplate>";

            return chain.SetVerticalScrollDownButtonTemplate<T>(controlTemplateStr, glyphPath);
        }

        public static T SetVerticalScrollUpButtonTemplate<T>(this T chain, string controlTemplateXAML, string glyphPath, string mouseOverColor) where T : FrameworkElement
        {
            RepeatButton repBtn = chain.GetVerticalScrollUpButton<T>();
            repBtn.Content = glyphPath;

            ControlTemplate cTemplate = new System.Windows.Controls.ControlTemplate(typeof(RepeatButton));
            string xaml = controlTemplateXAML;

            MemoryStream sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));
            ParserContext pc = new ParserContext();
            pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
            pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
            var repBtnTemplate = (ControlTemplate)XamlReader.Load(sr, pc);
            repBtn.Template = repBtnTemplate;

            return chain;
        }

        public static T SetVerticalScrollUpButtonColors<T>(this T chain, string backgroundColor, string mouseOverColor, string pressedColorTop, string pressedColorMid, string pressedColorBottom, string glyphColor, string pressedGlyphColor, string glyphPath) where T : FrameworkElement
        {
            string cornerRadius = "0";
            string borderColor = "Gray";
            Thickness borderThickness = new Thickness(0, 0, 0, 0);

            chain.SetVerticalScrollUpButtonColors(backgroundColor, mouseOverColor, pressedColorTop, pressedColorMid, pressedColorBottom, cornerRadius, borderColor, borderThickness, glyphColor, pressedGlyphColor, glyphPath);

            return chain;
        }

        public static T SetVerticalScrollUpButtonColors<T>(this T chain, string backgroundColor, string mouseOverColor, string pressedColorTop, string pressedColorMid, string pressedColorBottom, string cornerRadius, string borderColor, Thickness borderThickness, string glyphColor, string pressedGlyphColor, string glyphPath) where T : FrameworkElement
        {
            string disabledColor = "Gray"; //this needs to target the  TargetName=\"Border\" in order to work
            string pressedColor4 = "Transparent";

            string controlTemplateStr = "<ControlTemplate TargetType=\"{x:Type RepeatButton}\"><ControlTemplate.Resources>  <Color x:Key=\"DisabledForeColor\">" + disabledColor + "</Color><Color x:Key=\"PressedColor1\">" + pressedColorBottom + "</Color><Color x:Key=\"PressedColor2\">" + pressedColorTop + "</Color><Color x:Key=\"PressedColor3\">" + pressedColorMid + "</Color><Color x:Key=\"PressedColor4\">" + pressedColor4 + "</Color><Color x:Key=\"RegularForeColor\">" + backgroundColor + "</Color><Color x:Key=\"RegularBorderColor\">" + borderColor + "</Color><Color x:Key=\"MouseOverColor\">" + mouseOverColor + "</Color><Color x:Key=\"GlyphForeColor\">" + glyphColor + "</Color><Color x:Key=\"PressedGlyphForeColor\">" + pressedGlyphColor + "</Color><SolidColorBrush x:Key=\"NormalBrush\" Color=\"{StaticResource RegularForeColor}\" /><SolidColorBrush x:Key=\"NormalBorderBrush\" Color=\"{StaticResource RegularBorderColor}\" /> <SolidColorBrush x:Key=\"MouseOverBrush\" Color=\"{StaticResource MouseOverColor}\"/>  <SolidColorBrush x:Key=\"DisabledForeBrush\" Color=\"{StaticResource DisabledForeColor}\"/><SolidColorBrush x:Key=\"GlyphBrush\" Color=\"{StaticResource GlyphForeColor}\"/><SolidColorBrush x:Key=\"PressedGlyphBrush\" Color=\"{StaticResource PressedGlyphForeColor}\"/>   <LinearGradientBrush x:Key=\"PressedForeBrush\" StartPoint=\"0,0\" EndPoint=\"0,1\"><GradientBrush.GradientStops><GradientStopCollection><GradientStop Color=\"{StaticResource PressedColor1}\" Offset=\"1.0\"/><GradientStop Color=\"{StaticResource PressedColor2}\" Offset=\"0.3\"/><GradientStop Color=\"{StaticResource PressedColor3}\" Offset=\"0.7\"/><GradientStop Color=\"{StaticResource PressedColor4}\" Offset=\"1.0\"/></GradientStopCollection></GradientBrush.GradientStops></LinearGradientBrush></ControlTemplate.Resources>  <Border Name=\"Border\" Margin=\"1\" CornerRadius=\"" + cornerRadius + "\" Background=\"{StaticResource NormalBrush}\" BorderBrush=\"{StaticResource NormalBorderBrush}\" BorderThickness=\"" + borderThickness + "\"><Path  Name=\"pathGlyph\" HorizontalAlignment=\"Center\" VerticalAlignment=\"Center\" Fill=\"{StaticResource GlyphBrush}\" Data=\"{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}\" /></Border>  <ControlTemplate.Triggers><Trigger Property=\"IsPressed\" Value=\"true\"><Setter TargetName=\"Border\" Property=\"Background\" Value=\"{StaticResource PressedForeBrush}\" /><Setter TargetName=\"pathGlyph\" Property=\"Fill\" Value=\"{StaticResource PressedGlyphBrush}\" /></Trigger><Trigger Property=\"IsEnabled\" Value=\"false\"><Setter Property=\"Foreground\" Value=\"{StaticResource DisabledForeBrush}\"/></Trigger><MultiTrigger><MultiTrigger.Conditions><Condition Property=\"IsMouseOver\" Value=\"true\" /><Condition Property=\"IsPressed\" Value=\"false\" /></MultiTrigger.Conditions><Setter TargetName=\"Border\" Property=\"Background\" Value=\"{StaticResource MouseOverBrush}\"/></MultiTrigger></ControlTemplate.Triggers></ControlTemplate>";

            return chain.SetVerticalScrollUpButtonTemplate<T>(controlTemplateStr, glyphPath, mouseOverColor);
        }

        public static T SetVerticalScrollThumbColors<T>(this T chain, string backgroundColor, string mouseOverColor, string pressedColor, string borderColor, string borderThickness, string cornerRadius) where T : FrameworkElement
        {
            string disabledColor = "Gray"; //this needs to target the  TargetName=\"Border\" in order to work

            return chain.SetVerticalScrollThumbTemplate("<ControlTemplate><ControlTemplate.Resources> <Color x:Key=\"DisabledForeColor\">" + disabledColor + "</Color><Color x:Key=\"BorderColor\">" + borderColor + "</Color><Color x:Key=\"MouseOverColor\">" + mouseOverColor + "</Color><Color x:Key=\"PressedForeColor\">" + pressedColor + "</Color><Color x:Key=\"FillBrushColor\">" + backgroundColor + "</Color><SolidColorBrush x:Key=\"FillBrush\" Color=\"{StaticResource FillBrushColor}\"/><SolidColorBrush x:Key=\"BorderBrush\" Color=\"{StaticResource BorderColor}\"/> <SolidColorBrush x:Key=\"MouseOverBrush\" Color=\"{StaticResource MouseOverColor}\"/>  <SolidColorBrush x:Key=\"PressedForeBrush\" Color=\"{StaticResource PressedForeColor}\" /><SolidColorBrush x:Key=\"DisabledForeBrush\" Color=\"{StaticResource DisabledForeColor}\"/></ControlTemplate.Resources> <Border  Name=\"Border\"  CornerRadius=\"" + cornerRadius + "\" Background=\"{StaticResource FillBrush}\"  BorderBrush=\"{StaticResource BorderBrush}\"           BorderThickness=\"" + borderThickness + "\" /><ControlTemplate.Triggers><Trigger Property=\"IsEnabled\" Value=\"false\"><Setter Property=\"Foreground\" Value=\"{StaticResource DisabledForeBrush}\"/></Trigger><Trigger Property=\"Thumb.IsDragging\" Value=\"true\"><Setter  TargetName=\"Border\"  Property=\"Background\" Value=\"{StaticResource PressedForeBrush}\" /></Trigger><MultiTrigger><MultiTrigger.Conditions><Condition Property=\"IsMouseOver\" Value=\"true\" /><Condition Property=\"Thumb.IsDragging\"  Value=\"false\" /></MultiTrigger.Conditions><Setter TargetName=\"Border\" Property=\"Background\" Value=\"{StaticResource MouseOverBrush}\"/></MultiTrigger></ControlTemplate.Triggers> </ControlTemplate>");
        }

        public static T SetVerticalScrollThumbColors<T>(this T chain, byte red, byte green, byte blue, byte alpha, string mouseOverColor, string pressedColor, string borderColor, string borderThickness, string cornerRadius)
            where T : FrameworkElement
        {
            string fillColor = BrushExt.CreateColorStringFromRGB(red, green, blue, alpha);
            return chain.SetVerticalScrollThumbColors<T>(fillColor, mouseOverColor, pressedColor, borderColor, borderThickness, cornerRadius);
        }

        public static RepeatButton GetVerticalPageDownButton<T>(this T chain)
            where T : FrameworkElement
        {
            Track tr = chain.GetVerticalScrollTrack();
            tr.ApplyTemplate();
            return tr.IncreaseRepeatButton;
        }

        public static RepeatButton GetVerticalPageUpButton<T>(this T chain)
            where T : FrameworkElement
        {
            Track tr = chain.GetVerticalScrollTrack();
            tr.ApplyTemplate();
            return tr.DecreaseRepeatButton;
        }

        public static T SetVerticalPageDownButtonTemplate<T>(this T chain, string controlTemplateXAML)
            where T : FrameworkElement
        {
            RepeatButton repBtn = chain.GetVerticalPageDownButton<T>();
            ControlTemplate cTemplate = new System.Windows.Controls.ControlTemplate(typeof(RepeatButton));
            string xaml = controlTemplateXAML;

            MemoryStream sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));
            ParserContext pc = new ParserContext();
            pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
            pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
            ControlTemplate repBtnTemplate = (ControlTemplate)XamlReader.Load(sr, pc);
            repBtn.Template = repBtnTemplate;
            return chain;
        }

        public static T SetVerticalPageDownButtonColors<T>(this T chain, string backgroundColor, string pressedColorTop, string pressedColorMid, string pressedColorBottom, string cornerRadius, string borderColor, Thickness borderThickness)
            where T : FrameworkElement
        {
            string disabledColor = "Gray"; //default
            string pressedColor4 = "White"; //default
            string glyphColor = "Black"; //default
            string controlTemplateStr = ("<ControlTemplate TargetType=\"{x:Type RepeatButton}\"><ControlTemplate.Resources><Color x:Key=\"DisabledForeColor\">" + disabledColor + "</Color><Color x:Key=\"PressedColor1\">" + pressedColorBottom + "</Color><Color x:Key=\"PressedColor2\">" + pressedColorTop + "</Color><Color x:Key=\"PressedColor3\">" + pressedColorMid + "</Color><Color x:Key=\"PressedColor4\">" + pressedColor4 + "</Color><Color x:Key=\"RegularForeColor\">" + backgroundColor + "</Color><Color x:Key=\"RegularBorderColor\">" + borderColor + "</Color><Color x:Key=\"GlyphForeColor\">" + glyphColor + "</Color><SolidColorBrush x:Key=\"NormalBrush\" Color=\"{StaticResource RegularForeColor}\" /><SolidColorBrush x:Key=\"NormalBorderBrush\" Color=\"{StaticResource RegularBorderColor}\" />  <SolidColorBrush x:Key=\"DisabledForeBrush\" Color=\"{StaticResource DisabledForeColor}\"/><SolidColorBrush x:Key=\"GlyphBrush\" Color=\"{StaticResource GlyphForeColor}\"/>  <LinearGradientBrush x:Key=\"PressedForeBrush\" StartPoint=\"0,0\" EndPoint=\"0,1\"><GradientBrush.GradientStops><GradientStopCollection><GradientStop Color=\"{StaticResource PressedColor1}\" Offset=\"1.0\"/><GradientStop Color=\"{StaticResource PressedColor2}\" Offset=\"0.3\"/><GradientStop Color=\"{StaticResource PressedColor3}\" Offset=\"0.7\"/><GradientStop Color=\"{StaticResource PressedColor4}\" Offset=\"1.0\"/></GradientStopCollection></GradientBrush.GradientStops></LinearGradientBrush></ControlTemplate.Resources><Border Name=\"Border\" Margin=\"1\" CornerRadius=\"" + cornerRadius + "\"  Background=\"{StaticResource NormalBrush}\" BorderBrush=\"{StaticResource NormalBorderBrush}\" BorderThickness=\"" + borderThickness + "\"><Path HorizontalAlignment=\"Center\" VerticalAlignment=\"Center\" Fill=\"{StaticResource GlyphBrush}\" Data=\"{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}\" /></Border><ControlTemplate.Triggers><Trigger Property=\"IsPressed\" Value=\"true\"><Setter TargetName=\"Border\" Property=\"Background\" Value=\"{StaticResource PressedForeBrush}\" /></Trigger><Trigger Property=\"IsEnabled\" Value=\"false\"><Setter Property=\"Foreground\" Value=\"{StaticResource DisabledForeBrush}\"/></Trigger></ControlTemplate.Triggers></ControlTemplate>");

            return chain.SetVerticalPageDownButtonTemplate(controlTemplateStr);
        }

        public static T SetVerticalPageDownButtonColors<T>(this T chain, string backgroundColor, string pressedColorTop, string pressedColorMid, string pressedColorBottom) where T : FrameworkElement
        {
            string buttonCornerRadius = "0";
            string borderColor = "Gray";
            Thickness borderThickness = new Thickness(0, 0, 0, 0);

            return chain.SetVerticalPageDownButtonColors<T>(backgroundColor, pressedColorTop, pressedColorMid, pressedColorBottom, buttonCornerRadius, borderColor, borderThickness);
        }

        public static T SetVerticalPageDownButtonColors<T>(this T chain, byte red, byte green, byte blue, byte alpha, string pressedColorTop, string pressedColorMid, string pressedColorBottom) where T : FrameworkElement
        {
            string buttonCornerRadius = "0";
            string borderColor = "Gray";
            Thickness borderThickness = new Thickness(0, 0, 0, 0);

            string backgroundColor = BrushExt.CreateColorStringFromRGB(red, green, blue, alpha);
            return chain.SetVerticalPageDownButtonColors(backgroundColor, pressedColorTop, pressedColorMid, pressedColorBottom, buttonCornerRadius, borderColor, borderThickness);
        }

        public static T SetVerticalPageDownButtonColors<T>(this T chain, byte red, byte green, byte blue, byte alpha, string pressedColorTop, string pressedColorMid, string pressedColorBottom, string buttonCornerRadius, string borderColor, Thickness borderThickness)  where T : FrameworkElement
        {
            string backgroundColor = BrushExt.CreateColorStringFromRGB(red, green, blue, alpha);
            return chain.SetVerticalPageDownButtonColors<T>(backgroundColor, pressedColorTop, pressedColorMid, pressedColorBottom, buttonCornerRadius, borderColor, borderThickness);
        }

        public static T SetVerticalPageUpButtonTemplate<T>(this T chain, string controlTemplateXAML)
            where T : FrameworkElement
        {
            RepeatButton repBtn = chain.GetVerticalPageUpButton<T>();
            ControlTemplate cTemplate = new System.Windows.Controls.ControlTemplate(typeof(RepeatButton));
            string xaml = controlTemplateXAML;

            MemoryStream sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));
            ParserContext pc = new ParserContext();
            pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
            pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
            ControlTemplate repBtnTemplate = (ControlTemplate)XamlReader.Load(sr, pc);
            repBtn.Template = repBtnTemplate;
            return chain;
        }

        public static T SetVerticalPageUpButtonColors<T>(this T chain, string backgroundColor, string pressedColorTop, string pressedColorMid, string pressedColorBottom, string cornerRadius, string regularBorderColor, Thickness borderThickness) where T : FrameworkElement
        {
            string disabledColor = "Gray"; //default
            string pressedColor4 = "White"; //default
            string glyphColor = "Black"; //default
            string controlTemplateStr = ("<ControlTemplate TargetType=\"{x:Type RepeatButton}\"><ControlTemplate.Resources><Color x:Key=\"DisabledForeColor\">" + disabledColor + "</Color><Color x:Key=\"PressedColor1\">" + pressedColorTop + "</Color><Color x:Key=\"PressedColor2\">" + pressedColorBottom + "</Color><Color x:Key=\"PressedColor3\">" + pressedColorMid + "</Color><Color x:Key=\"PressedColor4\">" + pressedColor4 + "</Color><Color x:Key=\"RegularForeColor\">" + backgroundColor + "</Color><Color x:Key=\"RegularBorderColor\">" + regularBorderColor + "</Color><Color x:Key=\"GlyphForeColor\">" + glyphColor + "</Color><SolidColorBrush x:Key=\"NormalBrush\" Color=\"{StaticResource RegularForeColor}\" /><SolidColorBrush x:Key=\"NormalBorderBrush\" Color=\"{StaticResource RegularBorderColor}\" />  <SolidColorBrush x:Key=\"DisabledForeBrush\" Color=\"{StaticResource DisabledForeColor}\"/><SolidColorBrush x:Key=\"GlyphBrush\" Color=\"{StaticResource GlyphForeColor}\"/>  <LinearGradientBrush x:Key=\"PressedForeBrush\" StartPoint=\"0,1\" EndPoint=\"0,0\"><GradientBrush.GradientStops><GradientStopCollection><GradientStop Color=\"{StaticResource PressedColor1}\" Offset=\"1.0\"/><GradientStop Color=\"{StaticResource PressedColor2}\" Offset=\"0.3\"/><GradientStop Color=\"{StaticResource PressedColor3}\" Offset=\"0.7\"/><GradientStop Color=\"{StaticResource PressedColor4}\" Offset=\"1.0\"/></GradientStopCollection></GradientBrush.GradientStops></LinearGradientBrush></ControlTemplate.Resources><Border Name=\"Border\" Margin=\"1\" CornerRadius=\"" + cornerRadius + "\"  Background=\"{StaticResource NormalBrush}\" BorderBrush=\"{StaticResource NormalBorderBrush}\" BorderThickness=\"" + borderThickness + "\"><Path HorizontalAlignment=\"Center\" VerticalAlignment=\"Center\" Fill=\"{StaticResource GlyphBrush}\" Data=\"{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}\" /></Border><ControlTemplate.Triggers><Trigger Property=\"IsPressed\" Value=\"true\"><Setter TargetName=\"Border\" Property=\"Background\" Value=\"{StaticResource PressedForeBrush}\" /></Trigger><Trigger Property=\"IsEnabled\" Value=\"false\"><Setter Property=\"Foreground\" Value=\"{StaticResource DisabledForeBrush}\"/></Trigger></ControlTemplate.Triggers></ControlTemplate>");

            return chain.SetVerticalPageUpButtonTemplate<T>(controlTemplateStr);
        }

        public static T SetVerticalPageUpButtonColors<T>(this T chain, string backgroundColor, string pressedColorTop, string pressedColorMid, string pressedColorBottom) where T : FrameworkElement
        {
            string buttonCornerRadius = "0";
            string borderColor = "Gray";
            Thickness borderThickness = new Thickness(0, 0, 0, 0);

            return chain.SetVerticalPageUpButtonColors<T>(backgroundColor, pressedColorTop, pressedColorMid, pressedColorBottom, buttonCornerRadius, borderColor, borderThickness);
        }

        public static T SetVerticalPageUpButtonColors<T>(this T chain, byte red, byte green, byte blue, byte alpha, string pressedColorTop, string pressedColorMid, string pressedColorBottom) where T : FrameworkElement
        {
            string buttonCornerRadius = "0";
            string borderColor = "Gray";
            Thickness borderThickness = new Thickness(0, 0, 0, 0);

            string backgroundColor = BrushExt.CreateColorStringFromRGB(red, green, blue, alpha);
            return chain.SetVerticalPageUpButtonColors(backgroundColor, pressedColorTop, pressedColorMid, pressedColorBottom, buttonCornerRadius, borderColor, borderThickness);
        }

        public static T SetVerticalPageUpButtonColors<T>(this T chain, string pressedColorTop, string pressedColorMid, string pressedColorBottom, string pressedColor4, byte red, byte green, byte blue, byte alpha, string buttonCornerRadius, string regularBorderColor, Thickness borderThickness) where T : FrameworkElement
        {
            string backgroundColor = BrushExt.CreateColorStringFromRGB(red, green, blue, alpha);
            return chain.SetVerticalPageUpButtonColors<T>(backgroundColor, pressedColorTop, pressedColorMid, pressedColorBottom, buttonCornerRadius, regularBorderColor, borderThickness);
        }

        public static T SetVerticalScrollThumbTemplate<T>(this T chain, string controlTemplateXAML)
            where T : FrameworkElement
        {
            Thumb tumb = chain.GetVerticalScrollThumb<T>();
            ControlTemplate cTemplate = new System.Windows.Controls.ControlTemplate(typeof(Thumb));
            string xaml = controlTemplateXAML;

            MemoryStream sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));
            ParserContext pc = new ParserContext();
            pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
            pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
            ControlTemplate thumbTemplate = (ControlTemplate)XamlReader.Load(sr, pc);
            tumb.Template = thumbTemplate;
            return chain;
        }

        public static ScrollBar GetHorizontalScrollbar<T>(this T chain)
            where T : FrameworkElement
        {
            ScrollViewer scroller = GetScrollViewer<T>(chain);

            scroller.ApplyTemplate();
            Grid g = (Grid)scroller.Template.FindName("Grid", scroller);

            ScrollBar horizontalBar = null;
            
            if(g!=null)
            {
                horizontalBar = (ScrollBar)g.Children[3];
            }
            else
            {
                horizontalBar = (ScrollBar)scroller.Template.FindName("PART_HorizontalScrollBar", scroller);
            }

            return horizontalBar;
        }

        public static T SetHorizontalScrollBarColor<T>(this T chain, Brush brush)
            where T : FrameworkElement
        {
            ScrollBar scrBar = chain.GetHorizontalScrollbar<T>();

            if (scrBar != null && brush != null)
            {
                scrBar.Background = brush;
            }

            return chain;
        }

        public static T SetHorizontalScrollBarColor<T>(this T chain, byte red, byte green, byte blue, byte alpha)
            where T : FrameworkElement
        {
            ScrollBar scrBar = chain.GetHorizontalScrollbar();
            if (scrBar != null)
            {
                scrBar.Background = (Brush)(new System.Windows.Media.SolidColorBrush(new
                System.Windows.Media.Color()
                {
                    R = red,
                    G = green,
                    B = blue,
                    A = alpha
                }));
            }

            return chain;
        }

        public static Track GetHorizontalScrollTrack<T>(this T chain)
            where T : FrameworkElement
        {
            ScrollBar verticalBar = chain.GetHorizontalScrollbar();
            verticalBar.ApplyTemplate();
            return verticalBar.Track;
        }

        public static Thumb GetHorizontalScrollThumb<T>(this T chain)
            where T : FrameworkElement
        {
            Track tr = chain.GetHorizontalScrollTrack();
            tr.ApplyTemplate();
            return tr.Thumb;
        }

        public static RepeatButton GetHorizontalScrollLeftButton<T>(this T chain)
            where T : FrameworkElement
        {
            ScrollBar verticalBar = chain.GetHorizontalScrollbar();
            verticalBar.ApplyTemplate();
            Grid grid = (Grid)verticalBar.Template.FindName("Bg", verticalBar); //Grid
            RepeatButton upButton = ((RepeatButton)grid.Children[0]);
            return upButton;
        }

        public static RepeatButton GetHorizontalScrollRightButton<T>(this T chain)
            where T : FrameworkElement
        {
            ScrollBar verticalBar = chain.GetHorizontalScrollbar<T>();
            verticalBar.ApplyTemplate();
            Grid grid = (Grid)verticalBar.Template.FindName("Bg", verticalBar); //Grid
            RepeatButton downButton = ((RepeatButton)grid.Children[2]);
            return downButton;
        }

        public static T SetHorizontalScrollRightButtonTemplate<T>(this T chain, string controlTemplateXAML, string glyphPath) where T : FrameworkElement
        {
            RepeatButton repBtn = chain.GetHorizontalScrollRightButton();
            repBtn.Content = glyphPath;
            ControlTemplate cTemplate = new System.Windows.Controls.ControlTemplate(typeof(RepeatButton));
            string xaml = controlTemplateXAML;

            MemoryStream sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));
            ParserContext pc = new ParserContext();
            pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
            pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
            var repBtnTemplate = (ControlTemplate)XamlReader.Load(sr, pc);
            repBtn.Template = repBtnTemplate;
            return chain;
        }
        
        public static T SetHorizontalScrollRightButtonColors<T>(this T chain, string backgroundColor, string mouseOverColor, string pressedColorLeft, string pressedColorMid, string pressedColorRight, string glyphColor, string pressedGlyphColor, string glyphPath) where T : FrameworkElement
        {
            string cornerRadius = "0";
            string borderColor = "Gray";
            Thickness borderThickness = new Thickness(0, 0, 0, 0);

            chain.SetHorizontalScrollRightButtonColors<T>(backgroundColor, mouseOverColor, pressedColorLeft, pressedColorMid, pressedColorRight, cornerRadius, borderColor, borderThickness, glyphColor, pressedGlyphColor, glyphPath);

            return chain;
        }

        public static T SetHorizontalScrollRightButtonColors<T>(this T chain, string backgroundColor, string mouseOverColor, string pressedColorLeft, string pressedColorMid, string pressedColorRight, string cornerRadius, string borderColor, Thickness borderThickness, string glyphColor, string pressedGlyphColor, string glyphPath)
            where T : FrameworkElement
        {
            string disabledColor = "Gray"; //default
            string pressedColor4 = "Transparent";

            string controlTemplateStr = "<ControlTemplate TargetType=\"{x:Type RepeatButton}\"><ControlTemplate.Resources>  <Color x:Key=\"DisabledForeColor\">" + disabledColor + "</Color><Color x:Key=\"PressedColor1\">" + pressedColorLeft + "</Color><Color x:Key=\"PressedColor2\">" + pressedColorMid + "</Color><Color x:Key=\"PressedColor3\">" + pressedColorRight + "</Color><Color x:Key=\"PressedColor4\">" + pressedColor4 + "</Color><Color x:Key=\"MouseOverColor\">" + mouseOverColor + "</Color><Color x:Key=\"RegularForeColor\">" + backgroundColor + "</Color><Color x:Key=\"RegularBorderColor\">" + borderColor + "</Color><Color x:Key=\"GlyphForeColor\">" + glyphColor + "</Color><Color x:Key=\"PressedGlyphForeColor\">" + pressedGlyphColor + "</Color><SolidColorBrush x:Key=\"NormalBrush\" Color=\"{StaticResource RegularForeColor}\" /><SolidColorBrush x:Key=\"NormalBorderBrush\" Color=\"{StaticResource RegularBorderColor}\" />   <SolidColorBrush x:Key=\"MouseOverBrush\" Color=\"{StaticResource MouseOverColor}\"/><SolidColorBrush x:Key=\"DisabledForeBrush\" Color=\"{StaticResource DisabledForeColor}\"/><SolidColorBrush x:Key=\"GlyphBrush\" Color=\"{StaticResource GlyphForeColor}\"/>  <SolidColorBrush x:Key=\"PressedGlyphBrush\" Color=\"{StaticResource PressedGlyphForeColor}\"/> <LinearGradientBrush x:Key=\"PressedForeBrush\" StartPoint=\"0,0\" EndPoint=\"1,0\"><GradientBrush.GradientStops><GradientStopCollection><GradientStop Color=\"{StaticResource PressedColor1}\" Offset=\"0.0\"/><GradientStop Color=\"{StaticResource PressedColor2}\" Offset=\"0.2\"/><GradientStop Color=\"{StaticResource PressedColor3}\" Offset=\"0.9\"/><GradientStop Color=\"{StaticResource PressedColor4}\" Offset=\"1.0\"/></GradientStopCollection></GradientBrush.GradientStops></LinearGradientBrush></ControlTemplate.Resources>  <Border Name=\"Border\" Margin=\"1\" CornerRadius=\"" + cornerRadius + "\" Background=\"{StaticResource NormalBrush}\" BorderBrush=\"{StaticResource NormalBorderBrush}\" BorderThickness=\"" + borderThickness + "\"><Path  Name=\"pathGlyph\" HorizontalAlignment=\"Center\" VerticalAlignment=\"Center\" Fill=\"{StaticResource GlyphBrush}\" Data=\"{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}\" /></Border>  <ControlTemplate.Triggers><Trigger Property=\"IsPressed\" Value=\"true\"><Setter TargetName=\"Border\" Property=\"Background\" Value=\"{StaticResource PressedForeBrush}\" /><Setter TargetName=\"pathGlyph\" Property=\"Fill\" Value=\"{StaticResource PressedGlyphBrush}\" /></Trigger><Trigger Property=\"IsEnabled\" Value=\"false\"><Setter Property=\"Foreground\" Value=\"{StaticResource DisabledForeBrush}\"/></Trigger><MultiTrigger><MultiTrigger.Conditions><Condition Property=\"IsMouseOver\" Value=\"true\" /><Condition Property=\"IsPressed\" Value=\"false\" /></MultiTrigger.Conditions><Setter TargetName=\"Border\" Property=\"Background\" Value=\"{StaticResource MouseOverBrush}\"/></MultiTrigger></ControlTemplate.Triggers></ControlTemplate>";

            return chain.SetHorizontalScrollRightButtonTemplate<T>(controlTemplateStr, glyphPath);
        }

        public static T SetHorizontalScrollLeftButtonTemplate<T>(this T chain, string controlTemplateXAML, string glyphPath) where T : FrameworkElement
        {
            RepeatButton repBtn = chain.GetHorizontalScrollLeftButton<T>();
            repBtn.Content = glyphPath;
            ControlTemplate cTemplate = new System.Windows.Controls.ControlTemplate(typeof(RepeatButton));
            string xaml = controlTemplateXAML;

            MemoryStream sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));
            ParserContext pc = new ParserContext();
            pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
            pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
            var repBtnTemplate = (ControlTemplate)XamlReader.Load(sr, pc);
            repBtn.Template = repBtnTemplate;
            return chain;
        }

        public static T SetHorizontalScrollLeftButtonColors<T>(this T chain, string backgroundColor, string mouseOverColor, string pressedColorLeft, string pressedColorMid, string pressedColorRight, string glyphColor, string pressedGlyphColor, string glyphPath) where T : FrameworkElement
        {
            string cornerRadius = "0";
            string borderColor = "Gray";
            Thickness borderThickness = new Thickness(0, 0, 0, 0);

            chain.SetHorizontalScrollLeftButtonColors<T>(backgroundColor, mouseOverColor, pressedColorLeft, pressedColorMid, pressedColorRight, cornerRadius, borderColor, borderThickness, glyphColor, pressedGlyphColor, glyphPath);

            return chain;
        }

        public static T SetHorizontalScrollLeftButtonColors<T>(this T chain, string backgroundColor, string mouseOverColor, string pressedColorLeft, string pressedColorMid, string pressedColorRight, string cornerRadius, string borderColor, Thickness borderThickness, string glyphColor, string pressedGlyphColor, string glyphPath) where T : FrameworkElement
        {
            string disabledColor = "Gray"; //default
            string pressedColor4 = "Transparent";

            string controlTemplateStr = "<ControlTemplate TargetType=\"{x:Type RepeatButton}\"><ControlTemplate.Resources>  <Color x:Key=\"DisabledForeColor\">" + disabledColor + "</Color><Color x:Key=\"PressedColor1\">" + pressedColorRight + "</Color><Color x:Key=\"PressedColor2\">" + pressedColorLeft + "</Color><Color x:Key=\"PressedColor3\">" + pressedColorMid + "</Color><Color x:Key=\"PressedColor4\">" + pressedColor4 + "</Color><Color x:Key=\"MouseOverColor\">" + mouseOverColor + "</Color><Color x:Key=\"RegularForeColor\">" + backgroundColor + "</Color><Color x:Key=\"RegularBorderColor\">" + borderColor + "</Color><Color x:Key=\"GlyphForeColor\">" + glyphColor + "</Color><Color x:Key=\"PressedGlyphForeColor\">" + pressedGlyphColor + "</Color><SolidColorBrush x:Key=\"NormalBrush\" Color=\"{StaticResource RegularForeColor}\" /><SolidColorBrush x:Key=\"NormalBorderBrush\" Color=\"{StaticResource RegularBorderColor}\" />   <SolidColorBrush x:Key=\"MouseOverBrush\" Color=\"{StaticResource MouseOverColor}\"/><SolidColorBrush x:Key=\"DisabledForeBrush\" Color=\"{StaticResource DisabledForeColor}\"/><SolidColorBrush x:Key=\"GlyphBrush\" Color=\"{StaticResource GlyphForeColor}\"/>  <SolidColorBrush x:Key=\"PressedGlyphBrush\" Color=\"{StaticResource PressedGlyphForeColor}\"/> <LinearGradientBrush x:Key=\"PressedForeBrush\" StartPoint=\"0,0\" EndPoint=\"1,0\"><GradientBrush.GradientStops><GradientStopCollection><GradientStop Color=\"{StaticResource PressedColor1}\" Offset=\"1.0\"/><GradientStop Color=\"{StaticResource PressedColor2}\" Offset=\"0.2\"/><GradientStop Color=\"{StaticResource PressedColor3}\" Offset=\"0.7\"/><GradientStop Color=\"{StaticResource PressedColor4}\" Offset=\"1.0\"/></GradientStopCollection></GradientBrush.GradientStops></LinearGradientBrush></ControlTemplate.Resources>  <Border Name=\"Border\" Margin=\"1\" CornerRadius=\"" + cornerRadius + "\" Background=\"{StaticResource NormalBrush}\" BorderBrush=\"{StaticResource NormalBorderBrush}\" BorderThickness=\"" + borderThickness + "\"><Path  Name=\"pathGlyph\" HorizontalAlignment=\"Center\" VerticalAlignment=\"Center\" Fill=\"{StaticResource GlyphBrush}\" Data=\"{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}\" /></Border>  <ControlTemplate.Triggers><Trigger Property=\"IsPressed\" Value=\"true\"><Setter TargetName=\"Border\" Property=\"Background\" Value=\"{StaticResource PressedForeBrush}\" /><Setter TargetName=\"pathGlyph\" Property=\"Fill\" Value=\"{StaticResource PressedGlyphBrush}\" /></Trigger><Trigger Property=\"IsEnabled\" Value=\"false\"><Setter Property=\"Foreground\" Value=\"{StaticResource DisabledForeBrush}\"/></Trigger><MultiTrigger><MultiTrigger.Conditions><Condition Property=\"IsMouseOver\" Value=\"true\" /><Condition Property=\"IsPressed\" Value=\"false\" /></MultiTrigger.Conditions><Setter TargetName=\"Border\" Property=\"Background\" Value=\"{StaticResource MouseOverBrush}\"/></MultiTrigger></ControlTemplate.Triggers></ControlTemplate>";

            return chain.SetHorizontalScrollLeftButtonTemplate<T>(controlTemplateStr, glyphPath);
        }

        public static T SetHorizontalScrollThumbColors<T>(this T chain, string backgroundColor, string mouseOverColor, string pressedColor, string borderColor, string borderThickness, string cornerRadius)
            where T : FrameworkElement
        {
            string disabledColor = "Gray"; //this needs to target the  TargetName=\"Border\" in order to work

            return chain.SetHorizontalScrollThumbTemplate("<ControlTemplate><ControlTemplate.Resources> <Color x:Key=\"DisabledForeColor\">" + disabledColor + "</Color><Color x:Key=\"BorderColor\">" + borderColor + "</Color><Color x:Key=\"MouseOverColor\">" + mouseOverColor + "</Color><Color x:Key=\"PressedForeColor\">" + pressedColor + "</Color><Color x:Key=\"FillBrushColor\">" + backgroundColor + "</Color><SolidColorBrush x:Key=\"FillBrush\" Color=\"{StaticResource FillBrushColor}\"/><SolidColorBrush x:Key=\"BorderBrush\" Color=\"{StaticResource BorderColor}\"/> <SolidColorBrush x:Key=\"MouseOverBrush\" Color=\"{StaticResource MouseOverColor}\"/>  <SolidColorBrush x:Key=\"PressedForeBrush\" Color=\"{StaticResource PressedForeColor}\" /><SolidColorBrush x:Key=\"DisabledForeBrush\" Color=\"{StaticResource DisabledForeColor}\"/></ControlTemplate.Resources> <Border  Name=\"Border\"  CornerRadius=\"" + cornerRadius + "\" Background=\"{StaticResource FillBrush}\"  BorderBrush=\"{StaticResource BorderBrush}\"           BorderThickness=\"" + borderThickness + "\" /><ControlTemplate.Triggers><Trigger Property=\"IsEnabled\" Value=\"false\"><Setter Property=\"Foreground\" Value=\"{StaticResource DisabledForeBrush}\"/></Trigger><Trigger Property=\"Thumb.IsDragging\" Value=\"true\"><Setter  TargetName=\"Border\"  Property=\"Background\" Value=\"{StaticResource PressedForeBrush}\" /></Trigger><MultiTrigger><MultiTrigger.Conditions><Condition Property=\"IsMouseOver\" Value=\"true\" /><Condition Property=\"Thumb.IsDragging\"  Value=\"false\" /></MultiTrigger.Conditions><Setter TargetName=\"Border\" Property=\"Background\" Value=\"{StaticResource MouseOverBrush}\"/></MultiTrigger></ControlTemplate.Triggers> </ControlTemplate>");
        }

        public static T SetHorizontalScrollThumbColors<T>(this T chain, byte red, byte green, byte blue, byte alpha, string mouseOverColor, string pressedColor, string borderColor, string borderThickness, string cornerRadius)
            where T : FrameworkElement
        {
            string fillColor = BrushExt.CreateColorStringFromRGB(red, green, blue, alpha);
            return chain.SetHorizontalScrollThumbColors<T>(fillColor, mouseOverColor, pressedColor, borderColor, borderThickness, cornerRadius);
        }

        public static T SetHorizontalScrollThumbTemplate<T>(this T chain, string controlTemplateXAML)
            where T : FrameworkElement
        {
            Thumb tumb = chain.GetHorizontalScrollThumb<T>();
            ControlTemplate cTemplate = new System.Windows.Controls.ControlTemplate(typeof(Thumb));
            string xaml = controlTemplateXAML;

            MemoryStream sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));
            ParserContext pc = new ParserContext();
            pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
            pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
            ControlTemplate thumbTemplate = (ControlTemplate)XamlReader.Load(sr, pc);
            tumb.Template = thumbTemplate;
            return chain;
        }

        public static RepeatButton GetHorizontalPageRightButton<T>(this T chain)
             where T : FrameworkElement
        {
            Track tr = chain.GetHorizontalScrollTrack<T>();
            tr.ApplyTemplate();
            return tr.IncreaseRepeatButton;
        }

        public static RepeatButton GetHorizontalPageLeftButton<T>(this T chain) where T : FrameworkElement
        {
            Track tr = chain.GetHorizontalScrollTrack<T>();
            tr.ApplyTemplate();
            return tr.DecreaseRepeatButton;
        }

        public static T SetHorizontalPageRightButtonTemplate<T>(this T chain, string controlTemplateXAML)
            where T : FrameworkElement
        {
            RepeatButton repBtn = chain.GetHorizontalPageRightButton();
            ControlTemplate cTemplate = new System.Windows.Controls.ControlTemplate(typeof(RepeatButton));
            string xaml = controlTemplateXAML;

            MemoryStream sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));
            ParserContext pc = new ParserContext();
            pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
            pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
            ControlTemplate repBtnTemplate = (ControlTemplate)XamlReader.Load(sr, pc);
            repBtn.Template = repBtnTemplate;
            return chain;
        }

        public static T SetHorizontalPageRightButtonColors<T>(this T chain, string backgroundColor, string pressedColorLeft, string pressedColorMid, string pressedColorRight) where T : FrameworkElement
        {
            string cornerRadius = "0";
            string borderColor = "Gray";
            Thickness borderThickness = new Thickness(0, 0, 0, 0);

            chain.SetHorizontalPageRightButtonColors<T>(backgroundColor, pressedColorLeft, pressedColorMid, pressedColorRight, borderColor, cornerRadius, borderThickness);
            return chain;
        }

        public static T SetHorizontalPageRightButtonColors<T>(this T chain, byte red, byte green, byte blue, byte alpha, string pressedColorLeft, string pressedColorMid, string pressedColorRight) where T : FrameworkElement
        {
            string cornerRadius = "0";
            string borderColor = "Gray";
            Thickness borderThickness = new Thickness(0, 0, 0, 0);

            string backgroundColor = BrushExt.CreateColorStringFromRGB(red, green, blue, alpha);
            chain.SetHorizontalPageRightButtonColors<T>(backgroundColor, pressedColorLeft, pressedColorMid, pressedColorRight, borderColor, cornerRadius, borderThickness);
            return chain;
        }

        public static T SetHorizontalPageRightButtonColors<T>(this T chain, string backgroundColor, string pressedColorLeft, string pressedColorMid, string pressedColorRight, string borderColor, string cornerRadius, Thickness borderThickness)  where T : FrameworkElement
        {
            string disabledColor = "Gray"; //default
            string pressedColor4 = "White"; //default
            string glyphColor = "Black"; //default

            string controlTemplateStr = ("<ControlTemplate TargetType=\"{x:Type RepeatButton}\"><ControlTemplate.Resources><Color x:Key=\"DisabledForeColor\">" + disabledColor + "</Color><Color x:Key=\"PressedColor1\">" + pressedColorRight + "</Color><Color x:Key=\"PressedColor2\">" + pressedColorLeft + "</Color><Color x:Key=\"PressedColor3\">" + pressedColorMid + "</Color><Color x:Key=\"PressedColor4\">" + pressedColor4 + "</Color><Color x:Key=\"RegularForeColor\">" + backgroundColor + "</Color><Color x:Key=\"RegularBorderColor\">" + borderColor + "</Color><Color x:Key=\"GlyphForeColor\">" + glyphColor + "</Color><SolidColorBrush x:Key=\"NormalBrush\" Color=\"{StaticResource RegularForeColor}\" /><SolidColorBrush x:Key=\"NormalBorderBrush\" Color=\"{StaticResource RegularBorderColor}\" />  <SolidColorBrush x:Key=\"DisabledForeBrush\" Color=\"{StaticResource DisabledForeColor}\"/><SolidColorBrush x:Key=\"GlyphBrush\" Color=\"{StaticResource GlyphForeColor}\"/>  <LinearGradientBrush x:Key=\"PressedForeBrush\" StartPoint=\"0,0\" EndPoint=\"1,0\"><GradientBrush.GradientStops><GradientStopCollection><GradientStop Color=\"{StaticResource PressedColor1}\" Offset=\"1.0\"/><GradientStop Color=\"{StaticResource PressedColor2}\" Offset=\"0.3\"/><GradientStop Color=\"{StaticResource PressedColor3}\" Offset=\"0.7\"/><GradientStop Color=\"{StaticResource PressedColor4}\" Offset=\"1.0\"/></GradientStopCollection></GradientBrush.GradientStops></LinearGradientBrush></ControlTemplate.Resources><Border Name=\"Border\" Margin=\"1\" CornerRadius=\"" + cornerRadius + "\"  Background=\"{StaticResource NormalBrush}\" BorderBrush=\"{StaticResource NormalBorderBrush}\" BorderThickness=\"" + borderThickness + "\"><Path HorizontalAlignment=\"Center\" VerticalAlignment=\"Center\" Fill=\"{StaticResource GlyphBrush}\" Data=\"{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}\" /></Border><ControlTemplate.Triggers><Trigger Property=\"IsPressed\" Value=\"true\"><Setter TargetName=\"Border\" Property=\"Background\" Value=\"{StaticResource PressedForeBrush}\" /></Trigger><Trigger Property=\"IsEnabled\" Value=\"false\"><Setter Property=\"Foreground\" Value=\"{StaticResource DisabledForeBrush}\"/></Trigger></ControlTemplate.Triggers></ControlTemplate>");

            return chain.SetHorizontalPageRightButtonTemplate<T>(controlTemplateStr);
        }

        public static T SetHorizontalPageRightButtonColors<T>(this T chain, byte red, byte green, byte blue, byte alpha, string pressedColorLeft, string pressedColorMid, string pressedColorRight, string regularBorderColor, string buttonCornerRadius, Thickness borderThickness)  where T : FrameworkElement
        {
            string backgroundColor = BrushExt.CreateColorStringFromRGB(red, green, blue, alpha);
            return chain.SetHorizontalPageRightButtonColors(backgroundColor, pressedColorLeft, pressedColorMid, pressedColorRight, regularBorderColor, buttonCornerRadius, borderThickness);
        }

        public static T SetHorizontalPageLeftButtonTemplate<T>(this T chain, string controlTemplateXAML)
             where T : FrameworkElement
        {
            RepeatButton repBtn = chain.GetHorizontalPageLeftButton();
            ControlTemplate cTemplate = new System.Windows.Controls.ControlTemplate(typeof(RepeatButton));
            string xaml = controlTemplateXAML;

            MemoryStream sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));
            ParserContext pc = new ParserContext();
            pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
            pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
            ControlTemplate repBtnTemplate = (ControlTemplate)XamlReader.Load(sr, pc);
            repBtn.Template = repBtnTemplate;
            return chain;
        }

        public static T SetHorizontalPageLeftButtonColors<T>(this T chain, string backgroundColor, string pressedColorLeft, string pressedColorMid, string pressedColorRight)
           where T : FrameworkElement
        {
            string cornerRadius = "0";
            string borderColor = "Gray";
            Thickness borderThickness = new Thickness(0, 0, 0, 0);

            chain.SetHorizontalPageLeftButtonColors<T>(backgroundColor, pressedColorLeft, pressedColorMid, pressedColorRight, borderColor, cornerRadius, borderThickness);
            return chain;
        }

        public static T SetHorizontalPageLeftButtonColors<T>(this T chain, byte red, byte green, byte blue, byte alpha, string pressedColorLeft, string pressedColorMid, string pressedColorRight)
             where T : FrameworkElement
        {
            string cornerRadius = "0";
            string borderColor = "Gray";
            Thickness borderThickness = new Thickness(0, 0, 0, 0);

            string backgroundColor = BrushExt.CreateColorStringFromRGB(red, green, blue, alpha);
            chain.SetHorizontalPageLeftButtonColors<T>(backgroundColor, pressedColorLeft, pressedColorMid, pressedColorRight, borderColor, cornerRadius, borderThickness);
            return chain;
        }

        public static T SetHorizontalPageLeftButtonColors<T>(this T chain, string backgroundColor, string pressedColorLeft, string pressedColorMid, string pressedColorRight, string borderColor, string cornerRadius, Thickness borderThickness)  where T : FrameworkElement
        {
            string disabledColor = "Gray"; //default
            string pressedColor4 = "White"; //default
            string glyphColor = "Black"; //default

            string controlTemplateStr = ("<ControlTemplate TargetType=\"{x:Type RepeatButton}\"><ControlTemplate.Resources><Color x:Key=\"DisabledForeColor\">" + disabledColor + "</Color><Color x:Key=\"PressedColor1\">" + pressedColorLeft + "</Color><Color x:Key=\"PressedColor2\">" + pressedColorRight + "</Color><Color x:Key=\"PressedColor3\">" + pressedColorMid + "</Color><Color x:Key=\"PressedColor4\">" + pressedColor4 + "</Color><Color x:Key=\"RegularForeColor\">" + backgroundColor + "</Color><Color x:Key=\"RegularBorderColor\">" + borderColor + "</Color><Color x:Key=\"GlyphForeColor\">" + glyphColor + "</Color><SolidColorBrush x:Key=\"NormalBrush\" Color=\"{StaticResource RegularForeColor}\" /><SolidColorBrush x:Key=\"NormalBorderBrush\" Color=\"{StaticResource RegularBorderColor}\" />  <SolidColorBrush x:Key=\"DisabledForeBrush\" Color=\"{StaticResource DisabledForeColor}\"/><SolidColorBrush x:Key=\"GlyphBrush\" Color=\"{StaticResource GlyphForeColor}\"/>  <LinearGradientBrush x:Key=\"PressedForeBrush\" StartPoint=\"1,0\" EndPoint=\"0,0\"><GradientBrush.GradientStops><GradientStopCollection><GradientStop Color=\"{StaticResource PressedColor1}\" Offset=\"1.0\"/><GradientStop Color=\"{StaticResource PressedColor2}\" Offset=\"0.3\"/><GradientStop Color=\"{StaticResource PressedColor3}\" Offset=\"0.7\"/><GradientStop Color=\"{StaticResource PressedColor4}\" Offset=\"1.0\"/></GradientStopCollection></GradientBrush.GradientStops></LinearGradientBrush></ControlTemplate.Resources><Border Name=\"Border\" Margin=\"1\" CornerRadius=\"" + cornerRadius + "\"  Background=\"{StaticResource NormalBrush}\" BorderBrush=\"{StaticResource NormalBorderBrush}\" BorderThickness=\"" + borderThickness + "\"><Path HorizontalAlignment=\"Center\" VerticalAlignment=\"Center\" Fill=\"{StaticResource GlyphBrush}\" Data=\"{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}\" /></Border><ControlTemplate.Triggers><Trigger Property=\"IsPressed\" Value=\"true\"><Setter TargetName=\"Border\" Property=\"Background\" Value=\"{StaticResource PressedForeBrush}\" /></Trigger><Trigger Property=\"IsEnabled\" Value=\"false\"><Setter Property=\"Foreground\" Value=\"{StaticResource DisabledForeBrush}\"/></Trigger></ControlTemplate.Triggers></ControlTemplate>");

            return chain.SetHorizontalPageLeftButtonTemplate<T>(controlTemplateStr);
        }

        public static T SetHorizontalPageLeftButtonColors<T>(this T chain, byte red, byte green, byte blue, byte alpha, string pressedColorLeft, string pressedColorMid, string pressedColorRight, string regularBorderColor, string buttonCornerRadius, Thickness borderThickness)  where T : FrameworkElement
        {
            string backgroundColor = BrushExt.CreateColorStringFromRGB(red, green, blue, alpha);
            return chain.SetHorizontalPageLeftButtonColors<T>(backgroundColor, pressedColorLeft, pressedColorMid, pressedColorRight, regularBorderColor, buttonCornerRadius, borderThickness);
        }

        #endregion

        //DEPRECATED CODE
        //This region commented out because logical scrolling seems buggy. Therefore, always force physical scrolling by setting CanContentScroll equal to false
        #region Manage Row Paging and Scrolling

        #region Thumb Step and Drag Delta

        //public static void SetThumbDragDeltaHandler<T>(T source, IScrollViewerStrategy svComposite)
        //     where T : FrameworkElement
        //{
        //    var prevScrollButtonUp = Observable.FromEventPattern<DragDeltaEventArgs>(source.GetVerticalScrollThumb(), "DragDelta");

        //    Action<EventPattern<DragDeltaEventArgs>> actionDelegate = pattern =>
        //    {
        //        ListBoxExt_DragDelta<T>(pattern.Sender, pattern.EventArgs, svComposite);
        //    };

        //    var dragDeltaDisposable = prevScrollButtonUp.Subscribe(actionDelegate);

        //    //Store IDisposable in Dictionary
        //    source.StoreSetting<T>("DragDeltaDisposable", new FasterWPF.CommonExt.ObservableDisposer(prevScrollButtonUp, dragDeltaDisposable, actionDelegate));
        //}

        //public static void SetHorizThumbDragDeltaHandler<T>(T source, IScrollViewerStrategy svComposite)
        //    where T : FrameworkElement
        //{
        //    var horizThumbDelta = Observable.FromEventPattern<DragDeltaEventArgs>(source.GetHorizontalScrollThumb<T>(), "DragDelta");

        //    Action<EventPattern<DragDeltaEventArgs>> actionDelegate = pattern =>
        //    {
        //        ListBoxExt_HorizDragDelta<T>(pattern.Sender, pattern.EventArgs, svComposite);
        //    };

        //    var dragDeltaDisposable = horizThumbDelta.Subscribe(actionDelegate);

        //    //Store IDisposable in Dictionary
        //    source.StoreSetting<T>("HorizDragDeltaDisposable", new FasterWPF.CommonExt.ObservableDisposer(horizThumbDelta, dragDeltaDisposable, actionDelegate));
        //}

        //static void ListBoxExt_HorizDragDelta<T>(object sender, DragDeltaEventArgs e, IScrollViewerStrategy svComposite)
        //    where T: FrameworkElement
        //{
        //    var myThumb = (Thumb)e.OriginalSource;
        //    T lbx = svComposite.GetParentContainerFromScrollViewerThumb<T>(myThumb);
        //    double change = e.HorizontalChange;

        //    int step = (int)lbx.GetSettingsDictionary()["HorizScrollViewerDeltaStep"];

        //    if (e.HorizontalChange > 0)
        //    {
        //        IterHelpers.ApplyLoop(step, j =>
        //        {
        //            lbx.GetScrollViewer<T>().LineRight();
        //        });
        //    }
        //    if (e.HorizontalChange < 0)
        //    {
        //        IterHelpers.ApplyLoop(step, j =>
        //        {
        //            lbx.GetScrollViewer<T>().LineLeft();
        //        });
        //    }
        //}

        //static void ListBoxExt_DragDelta<T>(object sender, DragDeltaEventArgs e, IScrollViewerStrategy svComposite)
        //     where T : FrameworkElement
        //{
        //    var myThumb = (Thumb)e.OriginalSource;
        //    T lbx = svComposite.GetParentContainerFromScrollViewerThumb<T>(myThumb);
        //    double change = e.VerticalChange;

        //    int step = (int)lbx.GetSettingsDictionary()["ScrollViewerDeltaStep"];

        //    if (e.VerticalChange > 0)
        //    {
        //        IterHelpers.ApplyLoop(step, j =>
        //        {
        //            lbx.GetScrollViewer().LineDown();
        //        });
        //    }
        //    if (e.VerticalChange < 0)
        //    {
        //        IterHelpers.ApplyLoop(step, j =>
        //        {
        //            lbx.GetScrollViewer().LineUp();
        //        });
        //    }
        //}
        #endregion

        #region Scroll and Page Down

        //public static void SetVerticalScrollButtonDownHandler<T>(T source)
        //        where T : FrameworkElement
        //{
        //    var prevScrollButtonDown = Observable.FromEventPattern<MouseButtonEventArgs>(source.GetVerticalScrollDownButton<T>(), "PreviewMouseLeftButtonDown");

        //    Action<EventPattern<MouseButtonEventArgs>> actionDelegate = pattern =>
        //    {
        //        // source.GetScrollViewer().LineDown();  //TAKE THIS OUT
        //        // pattern.EventArgs.Handled = true;
        //    };

        //    var prevMouseDisposable = prevScrollButtonDown.Subscribe(actionDelegate);

        //    //set initial default values
        //    SetVerticalScrollDownButtonDelayAndInterval<T>(source);

        //    var prevRepeatButtonScrollDownClick = Observable.FromEventPattern<RoutedEventArgs>(source.GetVerticalScrollDownButton(), "Click");

        //    Action<EventPattern<RoutedEventArgs>> actionDelegate2 = pattern =>
        //    {
        //        int step = (int)source.GetSettingsDictionary()["ScrollViewerScrollDownStep"];
        //        IterHelpers.ApplyLoop(step, j =>
        //        {
        //            source.GetScrollViewer().LineDown();

        //            source.GetScrollViewer().CanContentScroll = false; //Logical scrolling seems buggy. Therefore, always force physical scrolling
        //        });

        //        pattern.EventArgs.Handled = true;
        //    };

        //    var prevRepeatScrollDownClickDisposable = prevRepeatButtonScrollDownClick.Subscribe(actionDelegate2);

        //    //Store IDisposable in Dictionary
        //    source.StoreSetting<T>("VerticalScrollDownDisposable", new FasterWPF.CommonExt.ObservableDisposer(prevScrollButtonDown, prevMouseDisposable, actionDelegate));
        //    source.StoreSetting<T>("VerticalScrollDownClickDisposable", new FasterWPF.CommonExt.ObservableDisposer(prevRepeatButtonScrollDownClick, prevRepeatScrollDownClickDisposable, actionDelegate2));
        //}

        //public static void SetVerticalPageButtonDownHandler<T>(T source)
        //        where T : FrameworkElement
        //{
        //    var prevScrollButtonDown = Observable.FromEventPattern<MouseButtonEventArgs>(source.GetVerticalPageDownButton<T>(), "PreviewMouseLeftButtonDown");

        //     Action<EventPattern<MouseButtonEventArgs>> actionDelegate = pattern =>
        //    {
        //        //int step = (int)source.GetSettingsDictionary()["ScrollViewerPageDownStep"];   //TAKE THIS OUT
        //        //ApplyLoop(step, j =>
        //        //{
        //        //    source.GetScrollViewer().LineDown();
        //        //});

        //        //pattern.EventArgs.Handled = true;
        //    };

        //    var prevMouseDisposable = prevScrollButtonDown.Subscribe(actionDelegate);

        //    //set initial default values
        //    SetVerticalPageDownButtonDelayAndInterval<T>(source);

        //    var prevRepeatButtonDownClick = Observable.FromEventPattern<RoutedEventArgs>(source.GetVerticalPageDownButton(), "Click");

        //    Action<EventPattern<RoutedEventArgs>> actionDelegate2 = pattern =>
        //    {
        //       int step = (int)source.GetSettingsDictionary()["ScrollViewerPageDownStep"];

        //       ScrollViewer closeOverViewer = source.GetScrollViewer();
        //       //IterHelpers.ApplyLoop(step, j =>
        //       //{
        //       //    closeOverViewer.LineDown();
        //       //});


        //       closeOverViewer.CanContentScroll = false;  //Logical scrolling seems buggy. Therefore, always force physical scrolling


        //       //   closeOverViewer.ScrollToVerticalOffset(closeOverViewer.VerticalOffset + step);

        //       pattern.EventArgs.Handled = true;
        //    };

        //    var prevRepeatDownClickDisposable = prevRepeatButtonDownClick.Subscribe(actionDelegate2);

        //    //Store IDisposable in Dictionary
        //    source.StoreSetting<T>("VerticalPageDownDisposable", new FasterWPF.CommonExt.ObservableDisposer(prevScrollButtonDown, prevMouseDisposable, actionDelegate));
        //    source.StoreSetting<T>("RepeatButtonDownClickDisposable", new FasterWPF.CommonExt.ObservableDisposer(prevRepeatButtonDownClick, prevRepeatDownClickDisposable, actionDelegate2));
        //}

        //  public static void SetCanContentScrollDuplicate<T>(T source)
        //          where T : FrameworkElement
        //  {
        //      ScrollViewer closeOverViewer = source.GetScrollViewer();
        //      closeOverViewer.CanContentScroll = false;  //Logical scrolling seems buggy. Therefore, always force physical scrolling

        // //     source.GetVerticalScrollDownButton().ClickMode = ClickMode.Press;
        ////      source.GetVerticalScrollDownButton().Delay = (int)source.GetSettingsDictionary()["ScrollViewerScrollDownDelay"];
        // //     source.GetVerticalScrollDownButton().Interval = (int)source.GetSettingsDictionary()["ScrollViewerScrollDownInterval"];
        //  }

        #endregion

        #region Scroll and Page Up

        //  public static void SetVerticalScrollUpButtonDelayAndInterval<T>(T source)
        //          where T : FrameworkElement
        //  {
        //  //    source.GetVerticalScrollUpButton().ClickMode = ClickMode.Press;
        //  //    source.GetVerticalScrollUpButton().Delay = (int)source.GetSettingsDictionary()["ScrollViewerScrollUpDelay"];
        //  //    source.GetVerticalScrollUpButton().Interval = (int)source.GetSettingsDictionary()["ScrollViewerScrollUpInterval"];
        //  }

        //  public static void SetVerticalPageUpButtonDelayAndInterval<T>(T source)
        //          where T : FrameworkElement
        //  {
        //  //    source.GetVerticalPageUpButton().ClickMode = ClickMode.Press;
        //  //    source.GetVerticalPageUpButton().Delay = (int)source.GetSettingsDictionary()["ScrollViewerPageUpDelay"];
        ////      source.GetVerticalPageUpButton().Interval = (int)source.GetSettingsDictionary()["ScrollViewerPageUpInterval"];
        //  }

        //  private static void setVerticalScrollButtonUpHandler<T>(T source)
        //          where T : FrameworkElement
        //  {
        //      var prevScrollButtonUp = Observable.FromEventPattern<MouseButtonEventArgs>(source.GetVerticalScrollUpButton(), "PreviewMouseLeftButtonDown");

        //      Action<EventPattern<MouseButtonEventArgs>> actionDelegate = pattern =>
        //      {
        //          // source.GetScrollViewer().LineUp();  //TAKE THIS OUT

        //          // pattern.EventArgs.Handled = true;
        //      };

        //      var prevMouseDisposable = prevScrollButtonUp.Subscribe(actionDelegate);

        //      //set initial default values
        //      SetVerticalScrollUpButtonDelayAndInterval(source);

        //      var prevRepeatScrollButtonUpClick = Observable.FromEventPattern<RoutedEventArgs>(source.GetVerticalScrollUpButton(), "Click");

        //      Action<EventPattern<RoutedEventArgs>> actionDelegate2 = pattern =>
        //      {
        //          int step = (int)source.GetSettingsDictionary()["ScrollViewerScrollUpStep"];
        //          IterHelpers.ApplyLoop(step, j =>
        //          {
        //              source.GetScrollViewer().LineUp();
        //          });

        //          pattern.EventArgs.Handled = true;
        //      };

        //      var prevRepeatScrollUpClickDisposable = prevRepeatScrollButtonUpClick.Subscribe(actionDelegate2);


        //      //Store IDisposable in Dictionary
        //      source.StoreSetting<T>("VerticalScrollUpDisposable", new FasterWPF.CommonExt.ObservableDisposer(prevScrollButtonUp, prevMouseDisposable, actionDelegate));
        //      source.StoreSetting<T>("VerticalScrollUpClickDisposable", new FasterWPF.CommonExt.ObservableDisposer(prevRepeatScrollButtonUpClick, prevRepeatScrollUpClickDisposable, actionDelegate2));
        //  }

        //  public static void SetVerticalPageButtonUpHandler<T>(T source)
        //          where T : FrameworkElement
        //  {
        //      var prevScrollButtonUp = Observable.FromEventPattern<MouseButtonEventArgs>(source.GetVerticalPageUpButton(), "PreviewMouseLeftButtonDown");

        //      Action<EventPattern<MouseButtonEventArgs>> actionDelegate = pattern =>
        //      {
        //          //int step = (int)source.GetSettingsDictionary()["ScrollViewerPageUpStep"];   //TAKE THIS OUT
        //          //ApplyLoop(step, j =>
        //          //{
        //          //    source.GetScrollViewer().LineUp();
        //          //});

        //          //pattern.EventArgs.Handled = true;
        //      };

        //      var prevMouseDisposable = prevScrollButtonUp.Subscribe(actionDelegate);

        //      //set initial default values
        //      SetVerticalPageUpButtonDelayAndInterval<T>(source);

        //      var prevRepeatButtonUpClick = Observable.FromEventPattern<RoutedEventArgs>(source.GetVerticalPageUpButton(), "Click");

        //      Action<EventPattern<RoutedEventArgs>> actionDelegate2 = pattern =>
        //      {
        //          int step = (int)source.GetSettingsDictionary()["ScrollViewerPageUpStep"];

        //          ScrollViewer closeOverViewer = source.GetScrollViewer();
        //          //IterHelpers.ApplyLoop(step, j =>
        //          //{
        //          //    source.GetScrollViewer().LineUp();
        //          //});


        //          closeOverViewer.CanContentScroll = false;  //Logical scrolling seems buggy. Therefore, always force physical scrolling


        //          // closeOverViewer.ScrollToVerticalOffset(closeOverViewer.VerticalOffset - step);

        //          pattern.EventArgs.Handled = true;
        //      };

        //      var prevRepeatUpClickDisposable = prevRepeatButtonUpClick.Subscribe(actionDelegate2);

        //      //Store IDisposable in Dictionary
        //      source.StoreSetting<T>("VerticalPageUpDisposable", new FasterWPF.CommonExt.ObservableDisposer(prevScrollButtonUp, prevMouseDisposable, actionDelegate));
        //      source.StoreSetting<T>("RepeatButtonUpClickDisposable", new FasterWPF.CommonExt.ObservableDisposer(prevRepeatButtonUpClick, prevRepeatUpClickDisposable, actionDelegate2));
        //  }

        #endregion

        #region Scroll and Page Left

        //private static void setHorizontalScrollLeftButtonDelayAndInterval<T>(T source)
        //        where T : FrameworkElement
        //{
        //    source.GetHorizontalScrollLeftButton().ClickMode = ClickMode.Press;
        //    source.GetHorizontalScrollLeftButton().Delay = (int)source.GetSettingsDictionary()["ScrollViewerScrollLeftDelay"];
        //    source.GetHorizontalScrollLeftButton().Interval = (int)source.GetSettingsDictionary()["ScrollViewerScrollLeftInterval"];
        //}

        //private static void setHorizontalPageLeftButtonDelayAndInterval<T>(T source)
        //        where T : FrameworkElement
        //{
        //    source.GetHorizontalPageLeftButton().ClickMode = ClickMode.Press;
        //    source.GetHorizontalPageLeftButton().Delay = (int)source.GetSettingsDictionary()["ScrollViewerPageLeftDelay"];
        //    source.GetHorizontalPageLeftButton().Interval = (int)source.GetSettingsDictionary()["ScrollViewerPageLeftInterval"];
        //}

        //public static void SetHorizontalScrollButtonLeftHandler<T>(T source)
        //        where T : FrameworkElement
        //{
        //    var prevScrollButtonLeft = Observable.FromEventPattern<MouseButtonEventArgs>(source.GetHorizontalScrollLeftButton<T>(), "PreviewMouseLeftButtonDown");

        //    Action<EventPattern<MouseButtonEventArgs>> actionDelegate = pattern =>
        //    {
        //        // source.GetScrollViewer().LineLeft();    //TAKE THIS OUT

        //        // pattern.EventArgs.Handled = true;
        //    };

        //    var prevMouseDisposable = prevScrollButtonLeft.Subscribe(actionDelegate);

        //    //set initial default values
        //    setHorizontalScrollLeftButtonDelayAndInterval(source);

        //    var prevRepeatScrollButtonLeftClick = Observable.FromEventPattern<RoutedEventArgs>(source.GetHorizontalScrollLeftButton(), "Click");

        //    Action<EventPattern<RoutedEventArgs>> actionDelegate2 = pattern =>
        //    {
        //        int step = (int)source.GetSettingsDictionary()["ScrollViewerScrollLeftStep"];
        //        IterHelpers.ApplyLoop(step, j =>
        //        {
        //            source.GetScrollViewer().LineLeft();
        //        });

        //        pattern.EventArgs.Handled = true;
        //    };

        //    var prevRepeatScrollLeftClickDisposable = prevRepeatScrollButtonLeftClick.Subscribe(actionDelegate2);

        //    //Store IDisposable in Dictionary
        //    source.StoreSetting<T>("HorizontalScrollLeftDisposable", new FasterWPF.CommonExt.ObservableDisposer(prevScrollButtonLeft, prevMouseDisposable, actionDelegate));
        //    source.StoreSetting<T>("HorizontalScrollLeftClickDisposable", new FasterWPF.CommonExt.ObservableDisposer(prevRepeatScrollButtonLeftClick, prevRepeatScrollLeftClickDisposable, actionDelegate2));
        //}

        //public static void SetHorizontalPageButtonLeftHandler<T>(T source)
        //        where T : FrameworkElement
        //{
        //    var prevScrollButtonLeft = Observable.FromEventPattern<MouseButtonEventArgs>(source.GetHorizontalPageLeftButton<T>(), "PreviewMouseLeftButtonDown");

        //    Action<EventPattern<MouseButtonEventArgs>> actionDelegate = pattern =>
        //    {
        //        //int step = (int)source.GetSettingsDictionary()["ScrollViewerPageLeftStep"];   //TAKE THIS OUT
        //        //ApplyLoop(step, j =>
        //        //{
        //        //    source.GetScrollViewer().LineLeft();
        //        //});

        //        //pattern.EventArgs.Handled = true;
        //    };

        //    var prevMouseDisposable = prevScrollButtonLeft.Subscribe(actionDelegate);

        //    //set initial default values
        //    setHorizontalPageLeftButtonDelayAndInterval(source);

        //    var prevRepeatButtonLeftClick = Observable.FromEventPattern<RoutedEventArgs>(source.GetHorizontalPageLeftButton(), "Click");

        //    Action<EventPattern<RoutedEventArgs>> actionDelegate2 = pattern =>
        //    {
        //        int step = (int)source.GetSettingsDictionary()["ScrollViewerPageLeftStep"];

        //        ScrollViewer closeOverViewer = source.GetScrollViewer();

        //        //IterHelpers.ApplyLoop(step, j =>
        //        //{
        //        //    source.GetScrollViewer().LineLeft();
        //        //});


        //        closeOverViewer.CanContentScroll = false;  //Logical scrolling seems buggy. Therefore, always force physical scrolling


        //        //  closeOverViewer.ScrollToVerticalOffset(closeOverViewer.VerticalOffset - step);

        //        pattern.EventArgs.Handled = true;
        //    };

        //    var prevRepeatLeftClickDisposable = prevRepeatButtonLeftClick.Subscribe(actionDelegate2);

        //    //Store IDisposable in Dictionary
        //    source.StoreSetting<T>("HorizontalPageLeftDisposable", new FasterWPF.CommonExt.ObservableDisposer(prevScrollButtonLeft, prevMouseDisposable, actionDelegate));
        //    source.StoreSetting<T>("RepeatButtonLeftClickDisposable", new FasterWPF.CommonExt.ObservableDisposer(prevRepeatButtonLeftClick, prevRepeatLeftClickDisposable, actionDelegate2));
        //}

        #endregion

        #region Scroll and Page Right

        //public static void SetHorizontalScrollButtonRightHandler<T>(T source)
        //        where T : FrameworkElement
        //{
        //    var prevScrollButtonRight = Observable.FromEventPattern<MouseButtonEventArgs>(source.GetHorizontalScrollRightButton<T>(), "PreviewMouseLeftButtonDown");

        //    Action<EventPattern<MouseButtonEventArgs>> actionDelegate = pattern =>
        //    {
        //        // source.GetScrollViewer().LineRight();   //TAKE THIS OUT

        //        // pattern.EventArgs.Handled = true;
        //    };

        //    var prevMouseDisposable = prevScrollButtonRight.Subscribe(actionDelegate);

        //    //set initial default values
        //    setHorizontalScrollRightButtonDelayAndInterval(source);

        //    var prevRepeatButtonScrollRightClick = Observable.FromEventPattern<RoutedEventArgs>(source.GetHorizontalScrollRightButton<T>(), "Click");

        //    Action<EventPattern<RoutedEventArgs>> actionDelegate2 = pattern =>
        //    {
        //        int step = (int)source.GetSettingsDictionary()["ScrollViewerScrollRightStep"];
        //        IterHelpers.ApplyLoop(step, j =>
        //        {
        //            source.GetScrollViewer().LineRight();
        //        });

        //        pattern.EventArgs.Handled = true;
        //    };

        //    var prevRepeatScrollRightClickDisposable = prevRepeatButtonScrollRightClick.Subscribe(actionDelegate2);

        //    //Store IDisposable in Dictionary
        //    source.StoreSetting<T>("HorizontalScrollRightDisposable", new FasterWPF.CommonExt.ObservableDisposer(prevScrollButtonRight, prevMouseDisposable, actionDelegate));
        //    source.StoreSetting<T>("HorizontalScrollRightClickDisposable", new FasterWPF.CommonExt.ObservableDisposer(prevRepeatButtonScrollRightClick, prevRepeatScrollRightClickDisposable, actionDelegate2));
        //}

        //public static void SetHorizontalPageButtonRightHandler<T>(T source)
        //        where T : FrameworkElement
        //{
        //    var prevScrollButtonRight = Observable.FromEventPattern<MouseButtonEventArgs>(source.GetHorizontalPageRightButton(), "PreviewMouseLeftButtonDown");


        //    Action<EventPattern<MouseButtonEventArgs>> actionDelegate = pattern =>
        //    {
        //        //int step = (int)source.GetSettingsDictionary()["ScrollViewerPageRightStep"]; //TAKE THIS OUT
        //        //ApplyLoop(step, j =>
        //        //{
        //        //    source.GetScrollViewer().LineRight();
        //        //});

        //        //pattern.EventArgs.Handled = true;
        //    };

        //    var prevMouseDisposable = prevScrollButtonRight.Subscribe(actionDelegate);

        //    //set initial default values
        //    setHorizontalPageRightButtonDelayAndInterval(source);

        //    var prevRepeatButtonRightClick = Observable.FromEventPattern<RoutedEventArgs>(source.GetHorizontalPageRightButton(), "Click");

        //    Action<EventPattern<RoutedEventArgs>> actionDelegate2 = pattern =>
        //    {
        //        int step = (int)source.GetSettingsDictionary()["ScrollViewerPageRightStep"];

        //        ScrollViewer closeOverViewer = source.GetScrollViewer();

        //        //IterHelpers.ApplyLoop(step, j =>
        //        //{
        //        //    source.GetScrollViewer().LineRight();
        //        //});


        //        closeOverViewer.CanContentScroll = false;  //Logical scrolling seems buggy. Therefore, always force physical scrolling


        //        //  closeOverViewer.ScrollToVerticalOffset(closeOverViewer.VerticalOffset + step);

        //        pattern.EventArgs.Handled = true;
        //    };

        //    var prevRepeatRightClickDisposable = prevRepeatButtonRightClick.Subscribe(actionDelegate2);

        //    //Store IDisposable in Dictionary
        //    source.StoreSetting<T>("HorizontalPageRightDisposable", new FasterWPF.CommonExt.ObservableDisposer(prevScrollButtonRight, prevMouseDisposable, actionDelegate));
        //    source.StoreSetting<T>("RepeatButtonRightClickDisposable", new FasterWPF.CommonExt.ObservableDisposer(prevRepeatButtonRightClick, prevRepeatRightClickDisposable, actionDelegate2));
        //}

        //private static void setHorizontalScrollRightButtonDelayAndInterval<T>(T source)
        //        where T : FrameworkElement
        //{
        //    source.GetHorizontalScrollRightButton().ClickMode = ClickMode.Press;
        //    source.GetHorizontalScrollRightButton().Delay = (int)source.GetSettingsDictionary()["ScrollViewerScrollRightDelay"];
        //    source.GetHorizontalScrollRightButton().Interval = (int)source.GetSettingsDictionary()["ScrollViewerScrollRightInterval"];
        //}

        //private static void setHorizontalPageRightButtonDelayAndInterval<T>(T source)
        //        where T : FrameworkElement
        //{
        //    source.GetHorizontalPageRightButton().ClickMode = ClickMode.Press;
        //    source.GetHorizontalPageRightButton().Delay = (int)source.GetSettingsDictionary()["ScrollViewerPageRightDelay"];
        //    source.GetHorizontalPageRightButton().Interval = (int)source.GetSettingsDictionary()["ScrollViewerPageRightInterval"];
        //}

        #endregion

        #endregion
        
    }
}
